@teselagen/ove 0.5.13 → 0.5.15
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.cjs.js +412 -317
- package/index.es.js +412 -317
- package/index.umd.js +253 -219
- package/package.json +2 -2
- package/src/GlobalDialogUtils.js +4 -1
- package/src/RowItem/Translations/AASliver.js +12 -11
- package/src/RowItem/Translations/Translation.js +41 -9
- package/src/withEditorInteractions/index.js +15 -28
- package/src/withEditorProps/index.js +9 -8
- package/style.css +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teselagen/ove",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@teselagen/sequence-utils": "0.3.24",
|
|
14
14
|
"@teselagen/range-utils": "0.3.7",
|
|
15
|
-
"@teselagen/ui": "0.4.
|
|
15
|
+
"@teselagen/ui": "0.4.11",
|
|
16
16
|
"@teselagen/file-utils": "0.3.16",
|
|
17
17
|
"@teselagen/bounce-loader": "0.3.11",
|
|
18
18
|
"@teselagen/bio-parsers": "0.4.18",
|
package/src/GlobalDialogUtils.js
CHANGED
|
@@ -23,7 +23,10 @@ export function showDialog({
|
|
|
23
23
|
?.className.split(" ")
|
|
24
24
|
.forEach(c => {
|
|
25
25
|
if (!c.trim()) return;
|
|
26
|
-
if (
|
|
26
|
+
if (
|
|
27
|
+
!c.trim().includes("veEditor") &&
|
|
28
|
+
!c.trim().includes("previewModeFullscreen")
|
|
29
|
+
) {
|
|
27
30
|
editorName = c;
|
|
28
31
|
}
|
|
29
32
|
});
|
|
@@ -36,8 +36,8 @@ function AASliver(props) {
|
|
|
36
36
|
path = isFiller
|
|
37
37
|
? "25,0 49,0 60,50 49,100 25,100 38,50 25,0"
|
|
38
38
|
: isTruncatedStart
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
? // ? "0,0 50,0 60,50 50,100 00,100 16,50 0,0"
|
|
40
|
+
`M ${roundedCorner / 3}, 0
|
|
41
41
|
L ${50 - roundedCorner / 3}, 0
|
|
42
42
|
Q 50 0 ${50 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
43
43
|
L ${60 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -59,9 +59,9 @@ function AASliver(props) {
|
|
|
59
59
|
L ${roundedCorner * dirX2}, ${roundedCorner * dirY2}
|
|
60
60
|
Q 0 0 ${roundedCorner / 3} 0
|
|
61
61
|
z`
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
: isTruncatedEnd
|
|
63
|
+
? // ? "24,0 74,0 84,50 74,100 24,100 40,50 24,0"
|
|
64
|
+
`M ${24 + roundedCorner / 3}, 0
|
|
65
65
|
L ${74 - roundedCorner / 3}, 0
|
|
66
66
|
Q 74 0 ${74 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
67
67
|
L ${84 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -83,7 +83,7 @@ function AASliver(props) {
|
|
|
83
83
|
L ${24 + roundedCorner * dirX2}, ${roundedCorner * dirY2}
|
|
84
84
|
Q 24 0 ${24 + roundedCorner / 3} 0
|
|
85
85
|
z`
|
|
86
|
-
|
|
86
|
+
: `M ${roundedCorner / 3}, 0
|
|
87
87
|
L ${74 - roundedCorner / 3}, 0
|
|
88
88
|
Q 74 0 ${74 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
89
89
|
L ${84 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -130,10 +130,10 @@ function AASliver(props) {
|
|
|
130
130
|
isFiller
|
|
131
131
|
? "25,0 49,0 60,50 49,100 25,100 38,50 25,0"
|
|
132
132
|
: isTruncatedStart
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
? "0,0 50,0 60,50 50,100 00,100 16,50 0,0"
|
|
134
|
+
: isTruncatedEnd
|
|
135
|
+
? "24,0 74,0 84,50 74,100 24,100 40,50 24,0"
|
|
136
|
+
: "0,0 74,0 85,50 74,100 0,100 16,50 0,0"
|
|
137
137
|
}
|
|
138
138
|
strokeWidth="5"
|
|
139
139
|
fill={color || "gray"}
|
|
@@ -148,7 +148,8 @@ function AASliver(props) {
|
|
|
148
148
|
/>
|
|
149
149
|
))}
|
|
150
150
|
|
|
151
|
-
{
|
|
151
|
+
{/* isTruncatedEnd && isTruncatedStart is the special case of a single base exon */}
|
|
152
|
+
{(!isFiller || (isTruncatedEnd && isTruncatedStart)) && (
|
|
152
153
|
<text
|
|
153
154
|
fontSize={25}
|
|
154
155
|
stroke="black"
|
|
@@ -57,31 +57,55 @@ class Translation extends React.Component {
|
|
|
57
57
|
);
|
|
58
58
|
|
|
59
59
|
//we then loop over all the amino acids in the sub range and draw them onto the row
|
|
60
|
+
let prevAaSliver;
|
|
61
|
+
let nextAaSliver = aminoAcidsForSubrange[1];
|
|
62
|
+
// The last index in the sequence
|
|
63
|
+
const lastIndex = aminoAcidsForSubrange.length - 1;
|
|
64
|
+
|
|
60
65
|
const translationSVG = aminoAcidsForSubrange.map(
|
|
61
66
|
function (aminoAcidSliver, index) {
|
|
67
|
+
if (aminoAcidSliver.positionInCodon === null) {
|
|
68
|
+
prevAaSliver = aminoAcidSliver;
|
|
69
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
70
|
+
return (
|
|
71
|
+
<rect
|
|
72
|
+
x={index * charWidth}
|
|
73
|
+
y={height / 2 - height / 16}
|
|
74
|
+
width={charWidth}
|
|
75
|
+
height={height / 8}
|
|
76
|
+
fill="grey"
|
|
77
|
+
stroke="black"
|
|
78
|
+
strokeWidth={1}
|
|
79
|
+
></rect>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
62
82
|
const isEndFiller =
|
|
63
|
-
index === 0 &&
|
|
83
|
+
(index === 0 || prevAaSliver?.positionInCodon === null) &&
|
|
64
84
|
aminoAcidSliver.positionInCodon === (annotation.forward ? 2 : 0);
|
|
65
|
-
|
|
85
|
+
|
|
86
|
+
const isStartFiller =
|
|
87
|
+
(index === lastIndex || nextAaSliver?.positionInCodon === null) &&
|
|
88
|
+
aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
89
|
+
|
|
66
90
|
let isTruncatedEnd =
|
|
67
|
-
index === 0
|
|
91
|
+
(index === 0 || prevAaSliver?.positionInCodon === null) &&
|
|
92
|
+
aminoAcidSliver.positionInCodon === 1;
|
|
68
93
|
let isTruncatedStart =
|
|
69
|
-
index ===
|
|
94
|
+
(index === lastIndex || nextAaSliver?.positionInCodon === null) &&
|
|
70
95
|
aminoAcidSliver.positionInCodon === 1;
|
|
96
|
+
|
|
71
97
|
if (!annotation.forward) {
|
|
72
98
|
const holder = isTruncatedEnd;
|
|
73
99
|
isTruncatedEnd = isTruncatedStart;
|
|
74
100
|
isTruncatedStart = holder;
|
|
75
101
|
}
|
|
76
|
-
const isStartFiller =
|
|
77
|
-
index === aminoAcidsForSubrange.length - 1 &&
|
|
78
|
-
aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
79
|
-
|
|
80
102
|
if (
|
|
81
103
|
aminoAcidSliver.positionInCodon !== 1 &&
|
|
82
104
|
!isStartFiller &&
|
|
83
105
|
!isEndFiller
|
|
84
106
|
) {
|
|
107
|
+
prevAaSliver = aminoAcidSliver;
|
|
108
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
85
109
|
return null;
|
|
86
110
|
}
|
|
87
111
|
const { gapsInside, gapsBefore } = getGaps(aminoAcidSliver.codonRange);
|
|
@@ -103,9 +127,17 @@ class Translation extends React.Component {
|
|
|
103
127
|
} else {
|
|
104
128
|
color = aminoAcid.color;
|
|
105
129
|
}
|
|
130
|
+
prevAaSliver = aminoAcidSliver;
|
|
131
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
132
|
+
|
|
106
133
|
return (
|
|
107
134
|
<AASliver
|
|
108
|
-
|
|
135
|
+
// isTruncatedEnd && isTruncatedStart is the special case of a single base exon
|
|
136
|
+
isFiller={
|
|
137
|
+
isEndFiller ||
|
|
138
|
+
isStartFiller ||
|
|
139
|
+
(isTruncatedEnd && isTruncatedStart)
|
|
140
|
+
}
|
|
109
141
|
isTruncatedEnd={isTruncatedEnd}
|
|
110
142
|
isTruncatedStart={isTruncatedStart}
|
|
111
143
|
onClick={function (event) {
|
|
@@ -202,7 +202,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
202
202
|
});
|
|
203
203
|
};
|
|
204
204
|
|
|
205
|
-
handlePaste = e => {
|
|
205
|
+
handlePaste = async e => {
|
|
206
206
|
const {
|
|
207
207
|
caretPosition = -1,
|
|
208
208
|
selectionLayer = { start: -1, end: -1 },
|
|
@@ -248,7 +248,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
248
248
|
if (!seqDataToInsert.sequence.length)
|
|
249
249
|
return window.toastr.warning("Sorry no valid base pairs to paste");
|
|
250
250
|
|
|
251
|
-
insertAndSelectHelper({
|
|
251
|
+
await insertAndSelectHelper({
|
|
252
252
|
seqDataToInsert,
|
|
253
253
|
props: this.props
|
|
254
254
|
});
|
|
@@ -344,7 +344,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
344
344
|
|
|
345
345
|
handleCopy = this.handleCutOrCopy();
|
|
346
346
|
|
|
347
|
-
handleDnaInsert = ({ useEventPositioning }) => {
|
|
347
|
+
handleDnaInsert = async ({ useEventPositioning }) => {
|
|
348
348
|
const {
|
|
349
349
|
caretPosition = -1,
|
|
350
350
|
selectionLayer = { start: -1, end: -1 },
|
|
@@ -371,8 +371,8 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
371
371
|
selectionLayer,
|
|
372
372
|
sequenceLength,
|
|
373
373
|
caretPosition,
|
|
374
|
-
handleInsert: seqDataToInsert => {
|
|
375
|
-
insertAndSelectHelper({
|
|
374
|
+
handleInsert: async seqDataToInsert => {
|
|
375
|
+
await insertAndSelectHelper({
|
|
376
376
|
props: this.props,
|
|
377
377
|
seqDataToInsert
|
|
378
378
|
});
|
|
@@ -383,7 +383,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
383
383
|
}
|
|
384
384
|
};
|
|
385
385
|
|
|
386
|
-
handleDnaDelete = (showToast = true) => {
|
|
386
|
+
handleDnaDelete = async (showToast = true) => {
|
|
387
387
|
const {
|
|
388
388
|
caretPosition = -1,
|
|
389
389
|
selectionLayer = { start: -1, end: -1 },
|
|
@@ -424,11 +424,13 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
424
424
|
isCaretAtEndOfSeq = true;
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
|
-
const [newSeqData] = wrappedInsertSequenceDataAtPositionOrRange(
|
|
427
|
+
const [newSeqData, {abortSeqChange}] = await wrappedInsertSequenceDataAtPositionOrRange(
|
|
428
428
|
{},
|
|
429
429
|
sequenceData,
|
|
430
430
|
rangeToDelete
|
|
431
431
|
);
|
|
432
|
+
console.log(`z3`)
|
|
433
|
+
if (abortSeqChange) return
|
|
432
434
|
updateSequenceData(newSeqData);
|
|
433
435
|
caretPositionUpdate(
|
|
434
436
|
isCaretAtEndOfSeq
|
|
@@ -1197,7 +1199,7 @@ function getGenbankFromSelection(selectedSeqData, sequenceData) {
|
|
|
1197
1199
|
};
|
|
1198
1200
|
}
|
|
1199
1201
|
|
|
1200
|
-
const insertAndSelectHelper = ({ seqDataToInsert, props }) => {
|
|
1202
|
+
const insertAndSelectHelper = async ({ seqDataToInsert, props }) => {
|
|
1201
1203
|
const {
|
|
1202
1204
|
updateSequenceData,
|
|
1203
1205
|
wrappedInsertSequenceDataAtPositionOrRange,
|
|
@@ -1207,31 +1209,16 @@ const insertAndSelectHelper = ({ seqDataToInsert, props }) => {
|
|
|
1207
1209
|
selectionLayer,
|
|
1208
1210
|
bpLimit
|
|
1209
1211
|
} = props;
|
|
1210
|
-
|
|
1211
|
-
// sequenceData,
|
|
1212
|
-
// caretPosition,
|
|
1213
|
-
// selectionLayer
|
|
1214
|
-
|
|
1215
|
-
// updateSequenceData(
|
|
1216
|
-
// wrappedInsertSequenceDataAtPositionOrRange(
|
|
1217
|
-
// seqDataToInsert,
|
|
1218
|
-
// sequenceData,
|
|
1219
|
-
// caretPosition > -1 ? caretPosition : selectionLayer
|
|
1220
|
-
// )
|
|
1221
|
-
// );
|
|
1222
|
-
|
|
1223
|
-
// const newSelectionLayerStart =
|
|
1224
|
-
// caretPosition > -1 ? caretPosition : (selectionLayer.start > selectionLayer.end ? 0 : selectionLayer.start);
|
|
1225
|
-
// selectionLayerUpdate({
|
|
1226
|
-
// start: newSelectionLayerStart,
|
|
1227
|
-
// end: newSelectionLayerStart + seqDataToInsert.sequence.length - 1
|
|
1228
|
-
// });
|
|
1229
|
-
const [newSeqData, { maintainOriginSplit }] =
|
|
1212
|
+
const [newSeqData, { maintainOriginSplit, abortSeqChange }] = await
|
|
1230
1213
|
wrappedInsertSequenceDataAtPositionOrRange(
|
|
1231
1214
|
seqDataToInsert,
|
|
1232
1215
|
sequenceData,
|
|
1233
1216
|
caretPosition > -1 ? caretPosition : selectionLayer
|
|
1234
1217
|
);
|
|
1218
|
+
console.log(`z4`)
|
|
1219
|
+
if (abortSeqChange) {
|
|
1220
|
+
throw new Error("abortSeqChange");
|
|
1221
|
+
}
|
|
1235
1222
|
if (bpLimit) {
|
|
1236
1223
|
if (newSeqData.sequence.length > bpLimit) {
|
|
1237
1224
|
window.toastr.error(
|
|
@@ -354,7 +354,7 @@ export default compose(
|
|
|
354
354
|
),
|
|
355
355
|
withHandlers({
|
|
356
356
|
wrappedInsertSequenceDataAtPositionOrRange: props => {
|
|
357
|
-
return (
|
|
357
|
+
return async (
|
|
358
358
|
_sequenceDataToInsert,
|
|
359
359
|
_existingSequenceData,
|
|
360
360
|
_caretPositionOrRange,
|
|
@@ -365,14 +365,15 @@ export default compose(
|
|
|
365
365
|
existingSequenceData,
|
|
366
366
|
caretPositionOrRange,
|
|
367
367
|
options
|
|
368
|
-
} =
|
|
369
|
-
? props.beforeSequenceInsertOrDelete(
|
|
368
|
+
} = (props.beforeSequenceInsertOrDelete
|
|
369
|
+
? await props.beforeSequenceInsertOrDelete(
|
|
370
370
|
tidyUpSequenceData(_sequenceDataToInsert),
|
|
371
371
|
tidyUpSequenceData(_existingSequenceData),
|
|
372
372
|
_caretPositionOrRange,
|
|
373
373
|
_options
|
|
374
374
|
) || {}
|
|
375
|
-
: {};
|
|
375
|
+
: {});
|
|
376
|
+
console.log(`zoink2`)
|
|
376
377
|
return [
|
|
377
378
|
insertSequenceDataAtPositionOrRange(
|
|
378
379
|
sequenceDataToInsert || _sequenceDataToInsert,
|
|
@@ -483,7 +484,7 @@ export default compose(
|
|
|
483
484
|
caretPositionUpdate(0);
|
|
484
485
|
},
|
|
485
486
|
|
|
486
|
-
handleReverseComplementSelection: props => () => {
|
|
487
|
+
handleReverseComplementSelection: props => async () => {
|
|
487
488
|
const {
|
|
488
489
|
sequenceData,
|
|
489
490
|
updateSequenceData,
|
|
@@ -499,7 +500,7 @@ export default compose(
|
|
|
499
500
|
range: selectionLayer
|
|
500
501
|
}
|
|
501
502
|
);
|
|
502
|
-
const [newSeqData] = wrappedInsertSequenceDataAtPositionOrRange(
|
|
503
|
+
const [newSeqData] = await wrappedInsertSequenceDataAtPositionOrRange(
|
|
503
504
|
reversedSeqData,
|
|
504
505
|
sequenceData,
|
|
505
506
|
selectionLayer,
|
|
@@ -510,7 +511,7 @@ export default compose(
|
|
|
510
511
|
updateSequenceData(newSeqData);
|
|
511
512
|
},
|
|
512
513
|
|
|
513
|
-
handleComplementSelection: props => () => {
|
|
514
|
+
handleComplementSelection: props => async () => {
|
|
514
515
|
const {
|
|
515
516
|
sequenceData,
|
|
516
517
|
updateSequenceData,
|
|
@@ -523,7 +524,7 @@ export default compose(
|
|
|
523
524
|
const comp = getComplementSequenceAndAnnotations(sequenceData, {
|
|
524
525
|
range: selectionLayer
|
|
525
526
|
});
|
|
526
|
-
const [newSeqData] = wrappedInsertSequenceDataAtPositionOrRange(
|
|
527
|
+
const [newSeqData] = await wrappedInsertSequenceDataAtPositionOrRange(
|
|
527
528
|
comp,
|
|
528
529
|
sequenceData,
|
|
529
530
|
selectionLayer,
|
package/style.css
CHANGED
|
@@ -9086,6 +9086,13 @@ button:not(:disabled):active {
|
|
|
9086
9086
|
width: 100%;
|
|
9087
9087
|
min-width: 170px;
|
|
9088
9088
|
}
|
|
9089
|
+
.tg-select.tg-select-as-tag {
|
|
9090
|
+
/* background-color: red; */
|
|
9091
|
+
border-radius: 4px;
|
|
9092
|
+
width: fit-content;
|
|
9093
|
+
color: white;
|
|
9094
|
+
border: 2px solid white;
|
|
9095
|
+
}
|
|
9089
9096
|
.tg-select.tg-select-as-tag .bp3-tag.bp3-minimal.bp3-intent-primary {
|
|
9090
9097
|
color: white !important;
|
|
9091
9098
|
}
|