@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ove",
3
- "version": "0.5.13",
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.10",
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",
@@ -23,7 +23,10 @@ export function showDialog({
23
23
  ?.className.split(" ")
24
24
  .forEach(c => {
25
25
  if (!c.trim()) return;
26
- if (!c.trim().includes("veEditor")) {
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
- ? // ? "0,0 50,0 60,50 50,100 00,100 16,50 0,0"
40
- `M ${roundedCorner / 3}, 0
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
- : isTruncatedEnd
63
- ? // ? "24,0 74,0 84,50 74,100 24,100 40,50 24,0"
64
- `M ${24 + roundedCorner / 3}, 0
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
- : `M ${roundedCorner / 3}, 0
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
- ? "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"
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
- {!isFiller && (
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
- // const isStartFiller = false
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 && aminoAcidSliver.positionInCodon === 1;
91
+ (index === 0 || prevAaSliver?.positionInCodon === null) &&
92
+ aminoAcidSliver.positionInCodon === 1;
68
93
  let isTruncatedStart =
69
- index === aminoAcidsForSubrange.length - 1 &&
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
- isFiller={isEndFiller || isStartFiller}
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
- } = props.beforeSequenceInsertOrDelete
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
  }