@teselagen/ove 0.7.30-beta.2 → 0.7.31

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/ove.css CHANGED
@@ -10724,6 +10724,61 @@ li.bp3-menu-divider:last-child {
10724
10724
  .veLabelText {
10725
10725
  user-select: none;
10726
10726
  }
10727
+ .veLabels {
10728
+ font-weight: lighter;
10729
+ }
10730
+
10731
+ .labelTspan:hover {
10732
+ fill: red !important;
10733
+ }
10734
+
10735
+ .labelText {
10736
+ cursor: pointer;
10737
+ }
10738
+
10739
+ .veEditor .veAnnotationHovered:not(.topLevelLabelGroup) {
10740
+ font-weight: bold;
10741
+ }
10742
+ .veEditor
10743
+ .veAnnotationHovered:not(.topLevelLabelGroup):not(
10744
+ .veCircularViewInternalLabelText
10745
+ ) {
10746
+ text-decoration: underline;
10747
+ }
10748
+
10749
+ .veEditor .veAnnotationHovered.veCutsiteLabel {
10750
+ font-weight: bold;
10751
+ text-decoration: underline;
10752
+ }
10753
+
10754
+ .bp3-dark .veLabels .veAnnotationHovered:not(.topLevelLabelGroup) {
10755
+ /* fill: white !important; */
10756
+ font-weight: normal;
10757
+ }
10758
+ .bp3-dark .veLabels .veAnnotationHovered rect {
10759
+ fill: rgb(64, 64, 92) !important;
10760
+ }
10761
+
10762
+ .partWithSelectedTag {
10763
+ font-size: 14px !important;
10764
+ font-weight: 900;
10765
+ text-decoration: underline;
10766
+ }
10767
+ .veCircularView .partWithSelectedTag.vePart .veLabelText {
10768
+ /* stroke: #ac68cc; */
10769
+ font-size: 15px !important;
10770
+ }
10771
+ .vePartLabel.partWithSelectedTag {
10772
+ font-size: large !important;
10773
+ }
10774
+
10775
+ .partWithSelectedTag path,
10776
+ path.partWithSelectedTag {
10777
+ stroke-width: 1.5 !important;
10778
+ }
10779
+ /* .veLabelLine {
10780
+ opacity: 0.1;
10781
+ } */
10727
10782
  .veRowView {
10728
10783
  overflow-x: visible;
10729
10784
  }
@@ -11197,61 +11252,6 @@ li.bp3-menu-divider:last-child {
11197
11252
  .simple-dialog .bp3-form-content {
11198
11253
  height: 40px;
11199
11254
  }
11200
- .veLabels {
11201
- font-weight: lighter;
11202
- }
11203
-
11204
- .labelTspan:hover {
11205
- fill: red !important;
11206
- }
11207
-
11208
- .labelText {
11209
- cursor: pointer;
11210
- }
11211
-
11212
- .veEditor .veAnnotationHovered:not(.topLevelLabelGroup) {
11213
- font-weight: bold;
11214
- }
11215
- .veEditor
11216
- .veAnnotationHovered:not(.topLevelLabelGroup):not(
11217
- .veCircularViewInternalLabelText
11218
- ) {
11219
- text-decoration: underline;
11220
- }
11221
-
11222
- .veEditor .veAnnotationHovered.veCutsiteLabel {
11223
- font-weight: bold;
11224
- text-decoration: underline;
11225
- }
11226
-
11227
- .bp3-dark .veLabels .veAnnotationHovered:not(.topLevelLabelGroup) {
11228
- /* fill: white !important; */
11229
- font-weight: normal;
11230
- }
11231
- .bp3-dark .veLabels .veAnnotationHovered rect {
11232
- fill: rgb(64, 64, 92) !important;
11233
- }
11234
-
11235
- .partWithSelectedTag {
11236
- font-size: 14px !important;
11237
- font-weight: 900;
11238
- text-decoration: underline;
11239
- }
11240
- .veCircularView .partWithSelectedTag.vePart .veLabelText {
11241
- /* stroke: #ac68cc; */
11242
- font-size: 15px !important;
11243
- }
11244
- .vePartLabel.partWithSelectedTag {
11245
- font-size: large !important;
11246
- }
11247
-
11248
- .partWithSelectedTag path,
11249
- path.partWithSelectedTag {
11250
- stroke-width: 1.5 !important;
11251
- }
11252
- /* .veLabelLine {
11253
- opacity: 0.1;
11254
- } */
11255
11255
  .veCircularViewMiddleOfVectorText {
11256
11256
  display: flex;
11257
11257
  height: 100%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ove",
3
- "version": "0.7.30-beta.2",
3
+ "version": "0.7.31",
4
4
  "main": "./src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -14,19 +14,19 @@
14
14
  "@blueprintjs/core": "3.54.0",
15
15
  "@hello-pangea/dnd": "16.2.0",
16
16
  "@risingstack/react-easy-state": "^6.3.0",
17
- "@teselagen/bio-parsers": "0.4.29-beta.1",
17
+ "@teselagen/bio-parsers": "0.4.28",
18
18
  "@teselagen/file-utils": "0.3.20",
19
- "@teselagen/range-utils": "0.3.14-beta.1",
19
+ "@teselagen/range-utils": "0.3.13",
20
20
  "@teselagen/react-list": "0.8.18",
21
- "@teselagen/sequence-utils": "0.3.32-beta.2",
22
- "@teselagen/ui": "0.8.6-beta.27",
21
+ "@teselagen/sequence-utils": "0.3.32",
22
+ "@teselagen/ui": "0.9.4",
23
23
  "@use-gesture/react": "10.3.0",
24
24
  "biomsa": "^0.2.4",
25
25
  "classnames": "^2.3.2",
26
- "color": "^5.0.0",
26
+ "clipboard": "^2.0.11",
27
+ "color": "^3.2.1",
27
28
  "combokeys": "^3.0.1",
28
29
  "copy-to-clipboard": "^3.3.1",
29
- "cypress-real-events": "^1.13.0",
30
30
  "deep-equal": "^1.1.1",
31
31
  "dom-to-image": "^2.6.0",
32
32
  "downloadjs": "^1.4.7",
@@ -57,15 +57,11 @@
57
57
  "redux-thunk": "2.4.1",
58
58
  "remark-gfm": "^4.0.0",
59
59
  "reselect": "^4.1.7",
60
+ "shortid": "2.2.16",
60
61
  "tg-use-local-storage-state": "^16.0.3",
61
62
  "to-regex-range": "5.0.1",
62
63
  "use-debounce": "^8.0.4",
63
- "validate.io-nonnegative-integer-array": "^1.0.1",
64
- "nanoid": "5.1.5"
65
- },
66
- "volta": {
67
- "node": "18.18.0",
68
- "yarn": "1.22.21"
64
+ "validate.io-nonnegative-integer-array": "^1.0.1"
69
65
  },
70
66
  "license": "MIT"
71
67
  }
@@ -7,7 +7,7 @@ declare const _default: ((state: any) => {
7
7
  forward: any;
8
8
  annotationTypePlural: string;
9
9
  isOrf: boolean;
10
- id: string;
10
+ id: any;
11
11
  }[]) & import('reselect').OutputSelectorFields<(args_0: any, args_1: any, args_2: any, args_3: any) => {
12
12
  start: number;
13
13
  end: number;
@@ -17,7 +17,7 @@ declare const _default: ((state: any) => {
17
17
  forward: any;
18
18
  annotationTypePlural: string;
19
19
  isOrf: boolean;
20
- id: string;
20
+ id: any;
21
21
  }[], {
22
22
  clearCache: () => void;
23
23
  }> & {
@@ -7,7 +7,7 @@ declare const _default: ((state: any) => any) & import('reselect').OutputSelecto
7
7
  forward: any;
8
8
  annotationTypePlural: string;
9
9
  isOrf: boolean;
10
- id: string;
10
+ id: any;
11
11
  }[], args_4: any, args_5: any, args_6: any[], args_7: any, args_8: any, args_9: any, args_10: any, args_11: any, args_12: any) => any, {
12
12
  clearCache: () => void;
13
13
  }> & {
@@ -15,9 +15,6 @@ import { connect } from "react-redux";
15
15
  import {
16
16
  Button,
17
17
  Intent,
18
- Popover,
19
- Menu,
20
- MenuItem,
21
18
  Tooltip,
22
19
  Icon,
23
20
  Spinner,
@@ -90,6 +87,7 @@ try {
90
87
 
91
88
  export const AlignmentView = props => {
92
89
  const {
90
+ dimensions,
93
91
  alignmentType,
94
92
  alignmentRunUpdate,
95
93
  alignmentName: _alignmentName,
@@ -103,13 +101,11 @@ export const AlignmentView = props => {
103
101
  sequenceLength,
104
102
  shouldAutosave,
105
103
  store,
106
- height,
104
+ height: _height,
107
105
  minimapLaneHeight,
108
106
  minimapLaneSpacing,
109
107
  isInPairwiseOverviewView,
110
108
  noVisibilityOptions,
111
- updateAlignmentSortOrder,
112
- alignmentSortOrder,
113
109
  handleBackButtonClicked,
114
110
  allowTrimming,
115
111
  additionalSelectionLayerRightClickedOptions,
@@ -121,6 +117,10 @@ export const AlignmentView = props => {
121
117
  style,
122
118
  unmappedSeqs
123
119
  } = props;
120
+ let height = _height;
121
+ if (dimensions && dimensions.height) {
122
+ height = dimensions.height;
123
+ }
124
124
 
125
125
  const {
126
126
  alignmentId,
@@ -616,7 +616,6 @@ export const AlignmentView = props => {
616
616
  } else {
617
617
  i = _i;
618
618
  }
619
-
620
619
  const track = alignmentTracks?.[i];
621
620
  if (!track) return null;
622
621
  const {
@@ -636,7 +635,7 @@ export const AlignmentView = props => {
636
635
  });
637
636
  const linearViewWidth =
638
637
  (alignmentData || sequenceData).sequence.length * charWidth;
639
- const name = sequenceData.name || sequenceData.id;
638
+ const name = alignmentData.name || sequenceData.name || sequenceData.id;
640
639
 
641
640
  const tickSpacing = massageTickSpacing(Math.ceil(120 / charWidth));
642
641
 
@@ -1261,7 +1260,7 @@ export const AlignmentView = props => {
1261
1260
  await navigator.clipboard.writeText(seqDataToCopy);
1262
1261
  };
1263
1262
 
1264
- const getAllAlignmentsFastaText = async () => {
1263
+ const copyAllAlignmentsFastaText = async () => {
1265
1264
  await navigator.clipboard.writeText(
1266
1265
  getAllAlignmentsFastaText()
1267
1266
  );
@@ -1281,7 +1280,7 @@ export const AlignmentView = props => {
1281
1280
  "copyAllAlignmentsFastaClipboardHelper",
1282
1281
  hotkey: "cmd+c",
1283
1282
  onClick: () => {
1284
- getAllAlignmentsFastaText();
1283
+ copyAllAlignmentsFastaText();
1285
1284
  window.toastr.success("Selection Copied");
1286
1285
  }
1287
1286
  },
@@ -1289,8 +1288,8 @@ export const AlignmentView = props => {
1289
1288
  text: `Copy Selection of ${name} as Fasta`,
1290
1289
  className:
1291
1290
  "copySpecificAlignmentFastaClipboardHelper",
1292
- onClick: () => {
1293
- copySpecificAlignmentFasta();
1291
+ onClick: e => {
1292
+ copySpecificAlignmentFasta(e);
1294
1293
  window.toastr.success(
1295
1294
  "Selection Copied As Fasta"
1296
1295
  );
@@ -1410,7 +1409,6 @@ export const AlignmentView = props => {
1410
1409
  updateLabelsForInViewFeatures();
1411
1410
  }
1412
1411
  };
1413
-
1414
1412
  return (
1415
1413
  <PinchHelper {...pinchHandler}>
1416
1414
  <ResizeSensor onResize={handleResize}>
@@ -1581,37 +1579,6 @@ export const AlignmentView = props => {
1581
1579
  {...alignmentVisibilityToolOptions}
1582
1580
  />
1583
1581
  )}
1584
- {updateAlignmentSortOrder && !isInPairwiseOverviewView && (
1585
- <Popover
1586
- minimal
1587
- content={
1588
- <Menu>
1589
- <MenuItem
1590
- active={true || alignmentSortOrder}
1591
- onClick={() => {
1592
- updateAlignmentSortOrder("Position");
1593
- }}
1594
- text="Position"
1595
- />
1596
- <MenuItem
1597
- active={false || alignmentSortOrder}
1598
- onClick={() => {
1599
- updateAlignmentSortOrder("Alphabetical");
1600
- }}
1601
- text="Alphabetical"
1602
- />
1603
- </Menu>
1604
- }
1605
- target={
1606
- <Button
1607
- small
1608
- text="Sort Order"
1609
- rightIcon="caret-down"
1610
- icon="sort"
1611
- />
1612
- }
1613
- />
1614
- )}
1615
1582
  {additionalTopEl}
1616
1583
  {saveMessage && (
1617
1584
  <div
@@ -4,7 +4,7 @@
4
4
  import { unparse } from "papaparse";
5
5
  import pluralize from "pluralize";
6
6
  import { SubmissionError, reduxForm } from "redux-form";
7
- import { nanoid } from "nanoid";
7
+ import shortid from "shortid";
8
8
  import CreateAnnotationsPage from "./CreateAnnotationsPage";
9
9
  import { formName } from "./constants";
10
10
  import { AutoAnnotateBpMatchingDialog } from "./AutoAnnotateBpMatchingDialog";
@@ -33,7 +33,7 @@ import {
33
33
  } from "@teselagen/ui";
34
34
  import { startCase } from "lodash-es";
35
35
  import withEditorProps from "./withEditorProps";
36
- import React, { useEffect, useState } from "react";
36
+ import { useEffect, useState } from "react";
37
37
  import { Colors, Tab, Tabs } from "@blueprintjs/core";
38
38
  import { typeField } from "./helperComponents/PropertiesDialog/typeField";
39
39
 
@@ -403,7 +403,7 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
403
403
  if (ann.matchType === "protein") {
404
404
  ann.sequence = convertProteinSeqToDNAIupac(ann.sequence);
405
405
  }
406
- const id = nanoid();
406
+ const id = shortid();
407
407
  annotationsToCheckById[id] = {
408
408
  ...ann,
409
409
  sequence: ann.isRegex
@@ -428,7 +428,7 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
428
428
  ...annotationsToCheckById[a.id],
429
429
  ...a,
430
430
  forward: a.strand !== -1,
431
- id: nanoid()
431
+ id: shortid()
432
432
  };
433
433
  toRet.color =
434
434
  toRet.color || getFeatureToColorMap()[toRet.type];
@@ -8,11 +8,19 @@ import { avoidOverlapWith } from "../drawAnnotations";
8
8
 
9
9
  const fontWidthToFontSize = 1.75;
10
10
 
11
- const getTextLength = text => {
12
- let len = (text || "Unlabeled").length;
11
+ export const getTextLengthWithCollapseSpace = (text, collapseWhiteSpace = true) => {
12
+ let displayText = text || "Unlabeled";
13
+ if (collapseWhiteSpace) {
14
+ displayText = displayText.replaceAll(
15
+ /\s+/g,
16
+ " "
17
+ );
18
+ }
19
+ let len = displayText.length;
13
20
  // eslint-disable-next-line no-control-regex
14
21
  const nonEnInputReg = /[^\x00-\xff]+/g;
15
- const nonEnStrings = (text || "Unlabeled").match(nonEnInputReg) || [];
22
+ const nonEnStrings =
23
+ displayText.match(nonEnInputReg) || [];
16
24
  nonEnStrings.forEach(str => (len += str.length * 0.5));
17
25
  return len;
18
26
  };
@@ -58,7 +66,7 @@ function Labels({
58
66
  _annotationCenterAngle + (rotationRadians || 0);
59
67
  return {
60
68
  ...label,
61
- width: getTextLength(label.text) * fontWidth,
69
+ width: getTextLengthWithCollapseSpace(label.text) * fontWidth,
62
70
  //three points define the label:
63
71
  innerPoint: {
64
72
  ...polarToSpecialCartesian(
@@ -214,42 +222,26 @@ const DrawLabelGroup = withHover(function ({
214
222
  }) {
215
223
  let { text = "Unlabeled" } = label;
216
224
 
217
- const textLength = getTextLength(text);
218
225
  let groupLabelXStart;
219
226
  //Add the number of unshown labels
220
227
  if (label.labelAndSublabels && label.labelAndSublabels.length > 1) {
221
- // if (label.x > 0) {
222
228
  text = "+" + (label.labelAndSublabels.length - 1) + "," + text;
223
- // } else {
224
- // text += ', +' + (label.labelAndSublabels.length - 1)
225
- // }
226
229
  }
227
230
 
228
- const labelLength = textLength * fontWidth;
229
- const maxLabelLength = labelAndSublabels.reduce(function (
230
- currentLength,
231
- { text = "Unlabeled" }
232
- ) {
233
- const _textLength = getTextLength(text);
234
- if (_textLength > currentLength) {
235
- return _textLength;
236
- }
237
- return currentLength;
238
- }, 0);
231
+ const labelLength = getTextLengthWithCollapseSpace(text) * fontWidth;
239
232
 
240
- const maxLabelWidth = maxLabelLength * fontWidth;
241
233
  const labelOnLeft = label.angle > Math.PI;
242
234
  let labelXStart = label.x - (labelOnLeft ? labelLength : 0);
235
+ const maxDistance =
236
+ (outerRadius + 90) * Math.max(1, circularViewWidthVsHeightRatio);
243
237
  if (condenseOverflowingXLabels) {
244
238
  const distancePastBoundary =
245
239
  Math.abs(label.x + (labelOnLeft ? -labelLength : labelLength)) -
246
- (outerRadius + 90) * Math.max(1, circularViewWidthVsHeightRatio);
247
- // Math.max(outerRadius (circularViewWidthVsHeightRatio / 2 + 80));
240
+ maxDistance;
241
+
248
242
  if (distancePastBoundary > 0) {
249
243
  const numberOfCharsToChop =
250
244
  Math.ceil(distancePastBoundary / fontWidth) + 2;
251
- // if (numberOfCharsToChop > text.length) numberOfCharsToChop = text.length
252
- //label overflows the boundaries!
253
245
  text = text.slice(0, -numberOfCharsToChop) + "..";
254
246
  groupLabelXStart =
255
247
  labelXStart +
@@ -261,17 +253,58 @@ const DrawLabelGroup = withHover(function ({
261
253
  const textYStart = label.y + dy / 2;
262
254
 
263
255
  //if label xStart or label xEnd don't fit within the canvas, we need to shorten the label..
264
-
265
256
  let content;
266
257
  const labelClass = ` veLabelText veLabel veCircularViewLabelText clickable ${label.color} `;
267
258
 
268
259
  if ((multipleLabels || groupLabelXStart !== undefined) && hovered) {
260
+ // Calculate the maximum label length for hovered status
261
+ const maxLabelLength = labelAndSublabels.reduce(function (
262
+ currentLength,
263
+ { text = "Unlabeled" }
264
+ ) {
265
+ const _textLength = getTextLengthWithCollapseSpace(text);
266
+ if (_textLength > currentLength) {
267
+ return _textLength;
268
+ }
269
+ return currentLength;
270
+ }, 0);
271
+ const maxLabelWidth = maxLabelLength * fontWidth;
272
+
273
+ labelXStart = label.x - (labelOnLeft ? maxLabelWidth : 0);
274
+ let distancePastBoundary = Math.abs(label.x + (labelOnLeft ? -maxLabelWidth : maxLabelWidth)) - maxDistance;
275
+ let lableRectWidth = maxLabelWidth - 14;
276
+
277
+ if (maxLabelWidth > maxDistance * 2) {
278
+ labelXStart = -maxDistance;
279
+ lableRectWidth = maxDistance * 2 - 24;
280
+ distancePastBoundary = maxLabelWidth - maxDistance * 2;
281
+ } else if (distancePastBoundary > 0) {
282
+ labelXStart += (labelOnLeft ? distancePastBoundary : -distancePastBoundary);
283
+ distancePastBoundary = 0;
284
+ }
285
+
269
286
  //HOVERED: DRAW MULTIPLE LABELS IN A RECTANGLE
270
287
  window.isLabelGroupOpen = true;
271
288
  let hoveredLabel;
272
- if (groupLabelXStart !== undefined) {
273
- labelXStart = groupLabelXStart;
289
+
290
+ let truncatedLabelAndSublabels;
291
+ if (distancePastBoundary > 0) {
292
+ truncatedLabelAndSublabels = labelAndSublabels.map(lable => {
293
+ const labelWidth = getTextLengthWithCollapseSpace(lable.text) * fontWidth;
294
+ const truncatedText =
295
+ labelWidth >= lableRectWidth
296
+ ? lable.text.slice(
297
+ 0,
298
+ -Math.ceil((labelWidth - lableRectWidth) / fontWidth) - 2
299
+ ) + ".."
300
+ : lable.text;
301
+ return {
302
+ ...lable,
303
+ text: truncatedText
304
+ };
305
+ });
274
306
  }
307
+
275
308
  labelAndSublabels.some(function (label) {
276
309
  if (label.id === hoveredId) {
277
310
  hoveredLabel = label;
@@ -317,7 +350,7 @@ const DrawLabelGroup = withHover(function ({
317
350
  // zIndex={10}
318
351
  x={labelXStart - 4}
319
352
  y={labelYStart - dy / 2}
320
- width={maxLabelWidth + 24}
353
+ width={lableRectWidth + 24}
321
354
  height={labelGroupHeight + 4}
322
355
  fill="white"
323
356
  stroke="black"
@@ -331,24 +364,26 @@ const DrawLabelGroup = withHover(function ({
331
364
  fontStyle: label.fontStyle
332
365
  }}
333
366
  >
334
- {labelAndSublabels.map(function (label, index) {
335
- return (
336
- <DrawGroupInnerLabel
337
- isSubLabel
338
- noRedux={noRedux}
339
- editorName={editorName}
340
- logHover
341
- key={"labelItem" + index}
342
- className={
343
- (label.className || "") +
344
- labelClass +
345
- " veDrawGroupInnerLabel"
346
- }
347
- id={label.id}
348
- {...{ labelXStart, label, fontWidth, index, dy }}
349
- />
350
- );
351
- })}
367
+ {(truncatedLabelAndSublabels || labelAndSublabels).map(
368
+ function (label, index) {
369
+ return (
370
+ <DrawGroupInnerLabel
371
+ isSubLabel
372
+ noRedux={noRedux}
373
+ editorName={editorName}
374
+ logHover
375
+ key={"labelItem" + index}
376
+ className={
377
+ (label.className || "") +
378
+ labelClass +
379
+ " veDrawGroupInnerLabel"
380
+ }
381
+ id={label.id}
382
+ {...{ labelXStart, label, fontWidth, index, dy }}
383
+ />
384
+ );
385
+ }
386
+ )}
352
387
  </text>
353
388
  </g>
354
389
  </PutMyParentOnTop>
@@ -364,7 +399,7 @@ const DrawLabelGroup = withHover(function ({
364
399
  data-title={label.title || label.text}
365
400
  {...avoidOverlapWith}
366
401
  x={labelXStart}
367
- textLength={getTextLength(text) * fontWidth}
402
+ textLength={getTextLengthWithCollapseSpace(text) * fontWidth}
368
403
  lengthAdjust="spacing"
369
404
  className={
370
405
  labelClass + label.className + (hovered ? " veAnnotationHovered" : "")
@@ -438,7 +473,7 @@ const DrawGroupInnerLabel = withHover(
438
473
  data-title={label.title}
439
474
  {...avoidOverlapWith}
440
475
  x={labelXStart}
441
- textLength={getTextLength(label.text) * fontWidth}
476
+ textLength={getTextLengthWithCollapseSpace(label.text) * fontWidth}
442
477
  lengthAdjust="spacing"
443
478
  onClick={label.onClick}
444
479
  onDoubleClick={e => {
@@ -1,5 +1,6 @@
1
1
  import { compose } from "redux";
2
2
  import pluralize from "pluralize";
3
+
3
4
  import { formName } from "./constants";
4
5
  import { typeField } from "./helperComponents/PropertiesDialog/typeField";
5
6
  import {
@@ -8,7 +9,7 @@ import {
8
9
  withSelectTableRecords,
9
10
  withSelectedEntities
10
11
  } from "@teselagen/ui";
11
- import React, { useEffect } from "react";
12
+ import { useEffect } from "react";
12
13
  import { hideDialog } from "./GlobalDialogUtils";
13
14
  import { startCase } from "lodash-es";
14
15
  import { tidyUpAnnotation } from "@teselagen/sequence-utils";
@@ -1,4 +1,4 @@
1
- import { nanoid } from "nanoid";
1
+ import shortid from "shortid";
2
2
 
3
3
  import { cloneDeep, startCase } from "lodash-es";
4
4
  import { convertRangeTo1Based } from "@teselagen/range-utils";
@@ -36,7 +36,7 @@ export function showDialog({
36
36
  dialogHolder.CustomModalComponent = ModalComponent;
37
37
  dialogHolder.props = props;
38
38
  dialogHolder.overrideName = overrideName;
39
- dialogHolder.setUniqKeyToForceRerender(nanoid());
39
+ dialogHolder.setUniqKeyToForceRerender(shortid());
40
40
  }
41
41
  export function hideDialog() {
42
42
  delete dialogHolder.dialogType;
@@ -8,6 +8,7 @@ import { reduce, values, startCase, filter, clamp } from "lodash-es";
8
8
  import { getRangeLength } from "@teselagen/range-utils";
9
9
  import { doesLabelFitInAnnotation } from "./utils";
10
10
  import getAnnotationNameAndStartStopString from "../utils/getAnnotationNameAndStartStopString";
11
+ import { getTextLengthWithCollapseSpace } from "../CircularView/Labels";
11
12
 
12
13
  const BUFFER_WIDTH = 6; //labels shouldn't be less than 6px from eachother on the same line
13
14
 
@@ -98,11 +99,11 @@ function Labels(props) {
98
99
  annotation = annotationRange;
99
100
  }
100
101
  const annotationLength =
101
- (
102
+ getTextLengthWithCollapseSpace(
102
103
  annotation.name ||
103
- (annotation.restrictionEnzyme && annotation.restrictionEnzyme.name) ||
104
- ""
105
- ).length * textWidth;
104
+ (annotation.restrictionEnzyme && annotation.restrictionEnzyme.name) ||
105
+ ""
106
+ ) * textWidth;
106
107
  let { xStart, width } = getXStartAndWidthOfRowAnnotation(
107
108
  annotationRange,
108
109
  bpsPerRow,
@@ -10,7 +10,7 @@ import {
10
10
  import { reduxForm, FieldArray } from "redux-form";
11
11
  import { anyToJson } from "@teselagen/bio-parsers";
12
12
  import { flatMap } from "lodash-es";
13
- import { nanoid } from "nanoid";
13
+ import uniqid from "shortid";
14
14
  import { cloneDeep } from "lodash-es";
15
15
  import classNames from "classnames";
16
16
 
@@ -155,7 +155,7 @@ class AlignmentTool extends React.Component {
155
155
  }
156
156
 
157
157
  hideModal();
158
- const alignmentId = nanoid();
158
+ const alignmentId = uniqid();
159
159
  // const alignmentIdMismatches = uniqid();
160
160
  createNewAlignment({
161
161
  id: alignmentId,
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { nanoid } from "nanoid";
2
+ import uuid from "shortid";
3
3
 
4
4
  import { reduxForm } from "redux-form";
5
5
 
@@ -58,7 +58,7 @@ class MergeFeaturesDialog extends React.Component {
58
58
  upsertFeature(
59
59
  {
60
60
  ...feat1,
61
- id: nanoid(),
61
+ id: uuid(),
62
62
  start: start - 1,
63
63
  end: end - 1,
64
64
  name