@teselagen/ove 0.7.27 → 0.7.28

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.
Files changed (304) hide show
  1. package/AASliver.js +187 -0
  2. package/AddLaddersDialog.js +82 -0
  3. package/AdditionalCutsiteInfoDialog.js +599 -0
  4. package/AlignmentView/Mismatches.d.ts +3 -3
  5. package/AlignmentVisibilityTool.js +105 -0
  6. package/AnnotationContainerHolder.js +20 -0
  7. package/AnnotationPositioner.js +27 -0
  8. package/AutoAnnotate.js +501 -0
  9. package/AutoAnnotateBpMatchingDialog.js +208 -0
  10. package/Axis.js +151 -0
  11. package/AxisNumbers.js +35 -0
  12. package/Browser.js +106 -0
  13. package/Caret.js +63 -0
  14. package/Chromatogram.js +293 -0
  15. package/CircularDnaSequence.js +73 -0
  16. package/CircularView/Labels/index.d.ts +1 -1
  17. package/CircularView/index.d.ts +0 -1
  18. package/CircularZoomMinimap.js +16 -0
  19. package/ColorPicker.js +30 -0
  20. package/CommandHotkeyHandler.js +44 -0
  21. package/CreateAnnotationsPage.d.ts +4 -4
  22. package/CreateAnnotationsPage.js +98 -0
  23. package/Cutsite.js +18 -0
  24. package/CutsiteProperties.js +176 -0
  25. package/CutsiteSelectionLayers.js +47 -0
  26. package/Cutsites.js +271 -0
  27. package/DeletionLayer.js +28 -0
  28. package/DigestTool/Ladder.d.ts +1 -1
  29. package/DropHandler.css +21 -0
  30. package/DropHandler.js +64 -0
  31. package/EditCaretPosition.js +234 -0
  32. package/EditTrackNameDialog.js +30 -0
  33. package/Feature.js +83 -0
  34. package/FeatureProperties.js +6 -0
  35. package/FillWindow.js +47 -0
  36. package/GenbankView.js +74 -0
  37. package/GeneralProperties.js +117 -0
  38. package/GenericAnnotationProperties.js +406 -0
  39. package/GlobalDialog.js +73 -0
  40. package/GlobalDialogUtils.js +110 -0
  41. package/GoToDialog.js +25 -0
  42. package/HorizontalPanelDragHandle.js +35 -0
  43. package/Keyboard.js +85 -0
  44. package/Labels.js +327 -0
  45. package/Ladder.css +20 -0
  46. package/Ladder.js +303 -0
  47. package/MeltingTemp.js +85 -0
  48. package/Menlo.ttf +0 -0
  49. package/Minimap.js +515 -0
  50. package/Mismatches.js +134 -0
  51. package/Monaco.ttf +0 -0
  52. package/MultipleSeqsDetectedOnImportDialog.js +74 -0
  53. package/Orf.js +109 -0
  54. package/OrfProperties.js +117 -0
  55. package/Orfs.js +35 -0
  56. package/PCRTool.js +179 -0
  57. package/PairwiseAlignmentView.js +68 -0
  58. package/Part.js +34 -0
  59. package/PartProperties.js +9 -0
  60. package/PassThrough.js +3 -0
  61. package/PerformantSelectionLayer.js +32 -0
  62. package/PinchHelper.js +24 -0
  63. package/PointedAnnotation.js +347 -0
  64. package/PositionAnnotationOnCircle.js +26 -0
  65. package/Primer.js +41 -0
  66. package/PrimerProperties.js +19 -0
  67. package/Reflex/index.d.ts +0 -1
  68. package/ReflexContainer.js +802 -0
  69. package/ReflexElement.js +160 -0
  70. package/ReflexEvents.js +77 -0
  71. package/ReflexSplitter.js +205 -0
  72. package/RenameSequenceDialog.js +7 -0
  73. package/RotateCircularViewSlider.js +93 -0
  74. package/RowView/index.d.ts +0 -1
  75. package/SelectDialog.js +150 -0
  76. package/SequenceName.js +15 -0
  77. package/SimpleCircularOrLinearView.js +381 -0
  78. package/SimpleOligoPreview.js +39 -0
  79. package/SingleEnzymeCutsiteInfo.js +139 -0
  80. package/ToolBar/ToolbarItem.d.ts +1 -3
  81. package/ToolbarItem.js +192 -0
  82. package/Translation.js +198 -0
  83. package/TranslationProperties.js +149 -0
  84. package/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  85. package/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  86. package/VeTopRightContainer.js +12 -0
  87. package/ZoomCircularViewSlider.js +62 -0
  88. package/ZoomLinearView.js +47 -0
  89. package/addAlignment.js +6 -0
  90. package/addMetaToActionCreators.js +12 -0
  91. package/addWrappedAddons.js +20 -0
  92. package/alignmentTool.js +503 -0
  93. package/alignments.js +379 -0
  94. package/annotationLabelVisibility.js +2 -0
  95. package/annotationSearchSelector.js +24 -0
  96. package/annotationTypes.js +35 -0
  97. package/annotationVisibility.js +196 -0
  98. package/annotationsToSupport.js +104 -0
  99. package/arrayToObjWithIds.js +17 -0
  100. package/arrayUtils.js +19 -0
  101. package/array_move.js +10 -0
  102. package/calculateTickMarkPositionsForGivenRange.js +47 -0
  103. package/caretPosition.js +27 -0
  104. package/cdsFeaturesSelector.js +9 -0
  105. package/charWidth.js +22 -0
  106. package/circular.js +19 -0
  107. package/circularSelector.js +4 -0
  108. package/clickAndDragUtils.js +576 -0
  109. package/coerceInitialValue.js +7 -0
  110. package/combineReducersDontIgnoreKeys.js +12 -0
  111. package/commandUtils.js +20 -0
  112. package/constants.js +2 -0
  113. package/copyOptions.js +34 -0
  114. package/createFragmentLines.js +120 -0
  115. package/createMergedDefaultStateReducer.js +30 -0
  116. package/createMetaAction.js +12 -0
  117. package/createSequenceInputPopup.js +290 -0
  118. package/createSequenceInputPopupStyle.css +87 -0
  119. package/createSimpleDialog.js +89 -0
  120. package/createYourOwnEnzyme.js +39 -0
  121. package/cutsiteLabelColorSelector.js +6 -0
  122. package/cutsiteTool.js +88 -0
  123. package/cutsitesByRangeSelector.js +5 -0
  124. package/cutsitesSelector.js +61 -0
  125. package/darkmode.css +98 -0
  126. package/defaultConfig.js +150 -0
  127. package/deletionLayers.js +36 -0
  128. package/description.js +21 -0
  129. package/digestTool.js +34 -0
  130. package/dnaToColor.js +17 -0
  131. package/downloadTool.js +39 -0
  132. package/draggableClassnames.js +5 -0
  133. package/drawAnnotations.js +440 -0
  134. package/drawDirectedPiePiece.js +142 -0
  135. package/editTool.js +49 -0
  136. package/editorSelector.js +2 -0
  137. package/editorUtils.js +205 -0
  138. package/estimateRowHeight.js +184 -0
  139. package/featureLengthsToHide.js +27 -0
  140. package/featureTool.js +34 -0
  141. package/features.js +19 -0
  142. package/featuresSelector.js +8 -0
  143. package/filteredCutsitesSelector.js +136 -0
  144. package/filteredFeaturesSelector.js +32 -0
  145. package/filteredPartsSelector.js +57 -0
  146. package/filteredPrimersSelector.js +27 -0
  147. package/filteredRestrictionEnzymesSelector.js +1 -0
  148. package/find.png +0 -0
  149. package/findTool.js +79 -0
  150. package/findToolConstants.js +1 -0
  151. package/frameTranslations.js +52 -0
  152. package/fullscreen.png +0 -0
  153. package/getAdditionalEnzymesSelector.js +46 -0
  154. package/getAngleForPositionMidpoint.js +3 -0
  155. package/getAnnotationClassnames.js +12 -0
  156. package/getAnnotationNameAndStartStopString.js +61 -0
  157. package/getBpsPerRow.js +19 -0
  158. package/getCutsiteLabelHeights.js +56 -0
  159. package/getGapMap.js +12 -0
  160. package/getGaps.js +27 -0
  161. package/getInternalLabel.js +40 -0
  162. package/getOveHotkeyDefs.js +12 -0
  163. package/getPairwiseOverviewLinearViewOptions.js +38 -0
  164. package/getRangeAnglesSpecial.js +12 -0
  165. package/getStructuredBases.js +97 -0
  166. package/getTrackFromEvent.js +25 -0
  167. package/getVisibleStartEnd.js +7 -0
  168. package/getXStartAndWidthFromNonCircularRange.js +12 -0
  169. package/getXStartAndWidthOfRangeWrtRow.js +27 -0
  170. package/getXStartAndWidthOfRowAnnotation.js +19 -0
  171. package/getYOffset.js +15 -0
  172. package/hoveredAnnotation.js +24 -0
  173. package/{html2canvas.esm--JN4fLQL.js → html2canvas.esm-DiGWN1gP.js} +187 -229
  174. package/{html2canvas.esm-B7d7VJmQ.cjs → html2canvas.esm-J1esNpMJ.cjs} +187 -229
  175. package/importTool.js +27 -0
  176. package/index.cjs.js +48165 -47142
  177. package/index.es.js +47699 -46676
  178. package/index.js +71 -0
  179. package/inlineFindTool.js +38 -0
  180. package/isElementInViewport.js +29 -0
  181. package/isEnzymeFilterAndSelector.js +1 -0
  182. package/isTargetWithinEl.js +6 -0
  183. package/labelLineIntensity.js +25 -0
  184. package/labelSize.js +23 -0
  185. package/ladderDefaults.js +25 -0
  186. package/lastSavedId.js +20 -0
  187. package/lineageLines.js +11 -0
  188. package/linear.png +0 -0
  189. package/makeStore.js +34 -0
  190. package/massageTickSpacing.js +19 -0
  191. package/materiallyAvailable.js +19 -0
  192. package/middleware.js +112 -0
  193. package/minimumOrfSize.js +24 -0
  194. package/minimumOrfSizeSelector.js +2 -0
  195. package/modalActions.js +3 -0
  196. package/moveCaret.js +58 -0
  197. package/name.js +19 -0
  198. package/normalizeAngle.js +3 -0
  199. package/normalizeAngleRange.js +9 -0
  200. package/oligoTool.js +30 -0
  201. package/onlyUpdateForKeysDeep.js +31 -0
  202. package/orfFrameToColorMap.js +10 -0
  203. package/orfTool.js +136 -0
  204. package/orfsSelector.js +15 -0
  205. package/ove.css +12107 -0
  206. package/package.json +6 -5
  207. package/panelsShown.js +294 -0
  208. package/partLengthsToHide.js +23 -0
  209. package/partOverhangs.js +6 -0
  210. package/partTagSearch.js +69 -0
  211. package/partTool.js +45 -0
  212. package/parts.js +19 -0
  213. package/partsSelector.js +8 -0
  214. package/pie.png +0 -0
  215. package/polarToSpecialCartesian.js +7 -0
  216. package/positionCutsites.js +6 -0
  217. package/prepareRowData.js +64 -0
  218. package/primerBases.js +221 -0
  219. package/primerLengthsToHide.js +27 -0
  220. package/primers.js +19 -0
  221. package/primersSelector.js +8 -0
  222. package/print.png +0 -0
  223. package/printTool.js +31 -0
  224. package/propertiesTool.js +40 -0
  225. package/proteinUtils.js +3 -0
  226. package/pureNoFunc.js +18 -0
  227. package/readOnly.js +25 -0
  228. package/redoTool.js +30 -0
  229. package/reflex-styles.css +128 -0
  230. package/reflex-styles.css.map +9 -0
  231. package/relaxLabelAngles.js +157 -0
  232. package/relaxLabels_DEPRECATED.js +105 -0
  233. package/replacementLayers.js +36 -0
  234. package/restrictionEnzymes.js +52 -0
  235. package/restrictionEnzymesSelector.js +34 -0
  236. package/rowviewContants.js +3 -0
  237. package/ruler.css +89 -0
  238. package/save.png +0 -0
  239. package/saveTool.js +44 -0
  240. package/searchLayersSelector.js +71 -0
  241. package/selectedAnnotations.js +89 -0
  242. package/selectedAnnotationsSelector.js +1 -0
  243. package/selectedCutsitesSelector.js +21 -0
  244. package/selectedPartTags.js +21 -0
  245. package/selectionLayer.js +25 -0
  246. package/selectors/annotationSearchSelector.d.ts +1 -1
  247. package/sequence.js +12 -0
  248. package/sequenceDataHistory.js +43 -0
  249. package/sequenceDataSelector.js +2 -0
  250. package/sequenceLengthSelector.js +5 -0
  251. package/sequenceSelector.js +4 -0
  252. package/sharedActionCreators.js +0 -0
  253. package/shouldFlipText.js +4 -0
  254. package/shouldRerender.js +27 -0
  255. package/showFileDialog.js +25 -0
  256. package/showGCContent.js +23 -0
  257. package/show_cut_sites.png +0 -0
  258. package/show_features.png +0 -0
  259. package/show_orfs.png +0 -0
  260. package/show_primers.png +0 -0
  261. package/simpleDialog.css +13 -0
  262. package/specialCutsiteFilterOptions.js +22 -0
  263. package/src/Editor/DropHandler.js +2 -1
  264. package/src/Editor/index.js +0 -2
  265. package/src/RowItem/StackedAnnotations/getStructuredBases.js +20 -6
  266. package/src/ToolBar/cutsiteTool.js +1 -1
  267. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -1
  268. package/style.css +3 -12100
  269. package/tagsToBoldSelector.js +2 -0
  270. package/toggle_views.svg +1 -0
  271. package/toolBar.js +23 -0
  272. package/translationSearchMatchesSelector.js +14 -0
  273. package/translations.js +20 -0
  274. package/translationsRawSelector.js +8 -0
  275. package/translationsSelector.js +137 -0
  276. package/typeField.js +24 -0
  277. package/undoTool.js +30 -0
  278. package/updateEditor.d.ts +1 -3
  279. package/updateEditor.js +200 -0
  280. package/updateLabelsForInViewFeatures.js +55 -0
  281. package/updateLabelsForInViewFeaturesCircView.js +41 -0
  282. package/updateTrackHelper.js +58 -0
  283. package/uppercaseSequenceMapFont.js +25 -0
  284. package/upsertDeleteActionGenerator.js +31 -0
  285. package/useAAColorType.js +8 -0
  286. package/useAdditionalOrfStartCodons.js +24 -0
  287. package/useAnnotationLimits.js +42 -0
  288. package/useChromatogramPrefs.js +31 -0
  289. package/useFormValue.js +7 -0
  290. package/useLadders.js +6 -0
  291. package/useMeltingTemp.js +7 -0
  292. package/useTmType.js +10 -0
  293. package/userDefinedHandlersAndOpts.js +61 -0
  294. package/utils/getAnnotationNameAndStartStopString.d.ts +1 -5
  295. package/utils/selectionLayer.d.ts +2 -2
  296. package/utils.js +37 -0
  297. package/versionHistory.js +26 -0
  298. package/versionHistoryTool.js +21 -0
  299. package/viewSubmenu.js +479 -0
  300. package/visibilityTool.js +39 -0
  301. package/withEditorInteractions/getBpsPerRow.d.ts +1 -3
  302. package/withHover.js +113 -0
  303. package/withRestrictionEnzymes.js +15 -0
  304. package/index.umd.js +0 -188322
@@ -0,0 +1,406 @@
1
+ import React from "react";
2
+ import {
3
+ DataTable,
4
+ withSelectedEntities,
5
+ CmdButton,
6
+ getTagProps,
7
+ getKeyedTagsAndTagOptions,
8
+ DropdownButton,
9
+ createCommandMenu,
10
+ popoverOverflowModifiers,
11
+ removeDuplicatesIcon
12
+ } from "@teselagen/ui";
13
+ import { map, upperFirst, pick, startCase, isFunction } from "lodash-es";
14
+ import {
15
+ AnchorButton,
16
+ ButtonGroup,
17
+ Icon,
18
+ Menu,
19
+ Tag,
20
+ Tooltip
21
+ } from "@blueprintjs/core";
22
+ import { getRangeLength } from "@teselagen/range-utils";
23
+ // import { Popover } from "@blueprintjs/core";
24
+ // import ColorPicker from "./ColorPicker";
25
+ import { connectToEditor } from "../../withEditorProps";
26
+ import { compose } from "recompose";
27
+ import commands from "../../commands";
28
+ import { sizeSchema } from "./utils";
29
+ import { showAddOrEditAnnotationDialog } from "../../GlobalDialogUtils";
30
+ import { typeField } from "./typeField";
31
+ import { getSequenceWithinRange } from "@teselagen/range-utils";
32
+ import { getReverseComplementSequenceString } from "@teselagen/sequence-utils";
33
+
34
+ const genericAnnotationProperties = ({
35
+ annotationType,
36
+ noType,
37
+ visSubmenu,
38
+ withTags,
39
+ withBases,
40
+ additionalFooterEls
41
+ }) => {
42
+ const annotationTypeUpper = upperFirst(annotationType);
43
+ class AnnotationProperties extends React.Component {
44
+ constructor(props) {
45
+ super(props);
46
+ this.commands = commands(this);
47
+ }
48
+ onRowSelect = ([record]) => {
49
+ if (!record) return;
50
+ const { dispatch, editorName } = this.props;
51
+ dispatch({
52
+ type: "SELECTION_LAYER_UPDATE",
53
+ payload: record,
54
+ meta: {
55
+ editorName
56
+ }
57
+ });
58
+ };
59
+ render() {
60
+ const {
61
+ readOnly,
62
+ annotations = {},
63
+ annotationVisibility,
64
+ sequenceLength,
65
+ selectionLayer,
66
+ sequence,
67
+ isProtein,
68
+ allPartTags,
69
+ annotationPropertiesSelectedEntities:
70
+ _annotationPropertiesSelectedEntities,
71
+ selectedAnnotationId
72
+ } = this.props;
73
+ const annotationPropertiesSelectedEntities =
74
+ _annotationPropertiesSelectedEntities.filter(a => annotations[a.id]);
75
+
76
+ const deleteAnnotation = this.props[`delete${annotationTypeUpper}`];
77
+
78
+ const annotationsToUse = map(annotations, annotation => {
79
+ return {
80
+ ...annotation,
81
+ ...(annotation.strand === undefined && {
82
+ strand: annotation.forward ? 1 : -1
83
+ }),
84
+ size: getRangeLength(annotation, sequenceLength)
85
+ };
86
+ });
87
+
88
+ const keyedPartTags = getKeyedTagsAndTagOptions(allPartTags) ?? {};
89
+
90
+ this.schema = {
91
+ fields: [
92
+ {
93
+ path: "name",
94
+ type: "string",
95
+
96
+ render: (name, ann) => {
97
+ const checked =
98
+ !this.props.annotationVisibility[
99
+ `${annotationType}IndividualToHide`
100
+ ][ann.id];
101
+
102
+ return (
103
+ <>
104
+ <Icon
105
+ data-tip="Hide/Show"
106
+ onClick={e => {
107
+ e.stopPropagation();
108
+ const upperType = startCase(annotationType);
109
+ if (checked) {
110
+ this.props[`hide${upperType}Individual`]([ann.id]);
111
+ } else {
112
+ this.props[`show${upperType}Individual`]([ann.id]);
113
+ }
114
+ }}
115
+ style={{
116
+ cursor: "pointer",
117
+ marginRight: 4,
118
+ marginTop: 3,
119
+ color: "darkgray"
120
+ }}
121
+ icon={`eye-${checked ? "open" : "off"}`}
122
+ ></Icon>
123
+ {name}
124
+ </>
125
+ );
126
+ }
127
+ },
128
+
129
+ ...(!withBases
130
+ ? []
131
+ : [
132
+ {
133
+ path: "bases",
134
+ type: "string",
135
+ render: (bases, primer) => {
136
+ let bps = bases;
137
+ if (!bases) {
138
+ bps = getSequenceWithinRange(primer, this.props.sequence);
139
+ if (!primer.forward) {
140
+ bps = getReverseComplementSequenceString(bps);
141
+ }
142
+ }
143
+ return bps;
144
+ }
145
+ }
146
+ ]),
147
+ ...(noType
148
+ ? []
149
+ : [
150
+ typeField,
151
+ {
152
+ path: "color",
153
+ type: "string",
154
+ width: 50,
155
+ render: color => {
156
+ return (
157
+ <div
158
+ style={{ height: 20, width: 20, background: color }}
159
+ />
160
+ // <ColorPickerPopover>
161
+ // <div style={{ height: 20, width: 20, background: color }} />
162
+ // </ColorPickerPopover>
163
+ );
164
+ }
165
+ }
166
+ ]),
167
+ sizeSchema(this.props.isProtein),
168
+ ...(withTags && this.props.allPartTags
169
+ ? [
170
+ {
171
+ path: "tags",
172
+ type: "string",
173
+ getValueToFilterOn: o => {
174
+ const toRet = (o.tags || [])
175
+ .map(tagId => {
176
+ const tag = keyedPartTags[tagId];
177
+ if (!tag) return "";
178
+ return tag.label;
179
+ })
180
+ .join(" ");
181
+ return toRet;
182
+ },
183
+ render: tags => {
184
+ return (
185
+ <div style={{ display: "flex" }}>
186
+ {(tags || []).map((tagId, i) => {
187
+ const tag = keyedPartTags[tagId];
188
+ if (!tag) return null;
189
+ return <Tag key={i} {...getTagProps(tag)}></Tag>;
190
+ })}
191
+ </div>
192
+ );
193
+ }
194
+ }
195
+ ]
196
+ : []),
197
+ { path: "strand", type: "number" }
198
+ ]
199
+ };
200
+
201
+ return (
202
+ <DataTable
203
+ topLeftItems={getVisFilter(
204
+ createCommandMenu(
205
+ isFunction(visSubmenu) ? visSubmenu(this.props) : visSubmenu,
206
+ this.commands,
207
+ {
208
+ useTicks: true
209
+ }
210
+ )
211
+ )}
212
+ annotationPropertiesSelectedEntities={
213
+ annotationPropertiesSelectedEntities
214
+ }
215
+ leftOfSearchBarItems={
216
+ <>
217
+ {!readOnly && (
218
+ <ButtonGroup style={{ marginTop: 3, marginRight: 4 }}>
219
+ <Tooltip
220
+ position="top"
221
+ modifiers={popoverOverflowModifiers}
222
+ content="New"
223
+ >
224
+ <AnchorButton
225
+ disabled={!sequenceLength}
226
+ icon="plus"
227
+ className="tgNewAnnBtn"
228
+ onClick={() => {
229
+ showAddOrEditAnnotationDialog({
230
+ type: annotationType,
231
+ annotation: pick(
232
+ selectionLayer,
233
+ "start",
234
+ "end",
235
+ "forward"
236
+ )
237
+ });
238
+ }}
239
+ ></AnchorButton>
240
+ </Tooltip>
241
+ <Tooltip
242
+ position="top"
243
+ modifiers={popoverOverflowModifiers}
244
+ content="Edit"
245
+ >
246
+ <AnchorButton
247
+ onClick={() => {
248
+ showAddOrEditAnnotationDialog({
249
+ type: annotationType,
250
+ annotation: annotationPropertiesSelectedEntities[0]
251
+ });
252
+ }}
253
+ disabled={
254
+ annotationPropertiesSelectedEntities.length !== 1
255
+ }
256
+ icon="edit"
257
+ ></AnchorButton>
258
+ </Tooltip>
259
+
260
+ {["feature"].includes(annotationType) && (
261
+ <CmdButton
262
+ text=""
263
+ icon="cog"
264
+ data-tip="Configure Feature Types"
265
+ cmd={this.commands.onConfigureFeatureTypesClick}
266
+ />
267
+ )}
268
+ {["part", "primer", "feature"].includes(annotationType) && (
269
+ <CmdButton
270
+ text=""
271
+ icon={removeDuplicatesIcon}
272
+ data-tip="Remove Duplicates"
273
+ cmd={
274
+ this.commands[
275
+ `showRemoveDuplicatesDialog${
276
+ annotationTypeUpper + "s"
277
+ }`
278
+ ]
279
+ }
280
+ />
281
+ )}
282
+
283
+ {additionalFooterEls && additionalFooterEls(this.props)}
284
+ <Tooltip
285
+ position="top"
286
+ modifiers={popoverOverflowModifiers}
287
+ content="Delete"
288
+ >
289
+ <AnchorButton
290
+ onClick={() => {
291
+ deleteAnnotation(annotationPropertiesSelectedEntities);
292
+ }}
293
+ className="tgDeleteAnnsBtn"
294
+ intent="danger"
295
+ disabled={!annotationPropertiesSelectedEntities.length}
296
+ icon="trash"
297
+ ></AnchorButton>
298
+ </Tooltip>
299
+ </ButtonGroup>
300
+ )}
301
+ {/* {createCommandMenu(
302
+ {
303
+ cmd: "featureFilterIndividualCmd",
304
+ // text: 'hahah',
305
+ shouldDismissPopover: false
306
+ },
307
+ this.commands,
308
+ {
309
+ useTicks: true
310
+ }
311
+ )} */}
312
+ {/* <CmdCheckbox
313
+ prefix="Show "
314
+ cmd={this.commands.featureFilterIndividualCmd}
315
+ /> */}
316
+ </>
317
+ }
318
+ onDoubleClick={annotation => {
319
+ showAddOrEditAnnotationDialog({
320
+ type: annotationType,
321
+ annotation
322
+ });
323
+ }}
324
+ withCheckboxes
325
+ showFeatureIndividual={this.props.showFeatureIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
326
+ hideFeatureIndividual={this.props.hideFeatureIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
327
+ showPartIndividual={this.props.showPartIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
328
+ hidePartIndividual={this.props.hidePartIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
329
+ showPrimerIndividual={this.props.showPrimerIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
330
+ hidePrimerIndividual={this.props.hidePrimerIndividual} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
331
+ annotationVisibility={annotationVisibility} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
332
+ featureLengthsToHide={this.props.featureLengthsToHide} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
333
+ primerLengthsToHide={this.props.primerLengthsToHide} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
334
+ partLengthsToHide={this.props.partLengthsToHide} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
335
+ sequence={sequence} //we need to pass this in order to force the DT to rerenderannotationVisibility={annotationVisibility}
336
+ noPadding
337
+ noFullscreenButton
338
+ onRowSelect={this.onRowSelect}
339
+ selectedIds={selectedAnnotationId}
340
+ formName="annotationProperties"
341
+ noRouter
342
+ isProtein={isProtein}
343
+ compact
344
+ isInfinite
345
+ schema={this.schema}
346
+ entities={annotationsToUse}
347
+ />
348
+ );
349
+ }
350
+ }
351
+
352
+ return compose(
353
+ connectToEditor(
354
+ ({
355
+ readOnly,
356
+ annotationVisibility = {},
357
+ sequenceData,
358
+ selectionLayer,
359
+ featureLengthsToHide,
360
+ primerLengthsToHide,
361
+ partLengthsToHide
362
+ }) => {
363
+ return {
364
+ annotationVisibility,
365
+ selectionLayer,
366
+ readOnly,
367
+ featureLengthsToHide,
368
+ primerLengthsToHide,
369
+ partLengthsToHide,
370
+ sequenceData,
371
+ sequence: sequenceData.sequence,
372
+ annotations: sequenceData[annotationType + "s"],
373
+ [annotationType + "s"]: sequenceData[annotationType + "s"],
374
+ sequenceLength: sequenceData.sequence.length
375
+ };
376
+ }
377
+ ),
378
+ // withEditorProps,
379
+ withSelectedEntities("annotationProperties")
380
+ )(AnnotationProperties);
381
+ };
382
+
383
+ export default genericAnnotationProperties;
384
+
385
+ // const ColorPickerPopover = ({ readOnly, onColorSelect, children }) => {
386
+ // return (
387
+ // <Popover
388
+ // disabled={readOnly}
389
+ // content={<ColorPicker onColorSelect={onColorSelect} />}
390
+ // >
391
+ // {children}
392
+ // </Popover>
393
+ // );
394
+ // };
395
+
396
+ export function getVisFilter(submenu) {
397
+ return (
398
+ <DropdownButton
399
+ style={{ marginTop: 3 }}
400
+ icon="eye-open"
401
+ className="propertiesVisFilter"
402
+ data-tip="Visibility Filter"
403
+ menu={<Menu>{submenu}</Menu>}
404
+ ></DropdownButton>
405
+ );
406
+ }
@@ -0,0 +1,73 @@
1
+ import React, { useState, useEffect } from "react";
2
+
3
+ import { dialogHolder, hideDialog } from "./GlobalDialogUtils";
4
+
5
+ import RenameSequenceDialog from "./helperComponents/RenameSequenceDialog";
6
+ import PrintDialog from "./helperComponents/PrintDialog";
7
+ import RemoveDuplicates from "./helperComponents/RemoveDuplicates";
8
+ import { MultipleSeqsDetectedOnImportDialog } from "./helperComponents/MultipleSeqsDetectedOnImportDialog";
9
+ import GoToDialog from "./helperComponents/GoToDialog";
10
+ import SelectDialog from "./helperComponents/SelectDialog";
11
+ import EnzymesDialog from "./helperComponents/EnzymesDialog";
12
+ import CreateCustomEnzyme from "./CreateCustomEnzyme";
13
+ import {
14
+ AdditionalCutsiteInfoDialog,
15
+ CompareEnzymeGroupsDialog
16
+ } from "./CutsiteFilter/AdditionalCutsiteInfoDialog";
17
+ import { AlignmentToolDialog } from "./ToolBar/alignmentTool";
18
+ import MergeFeaturesDialog from "./helperComponents/MergeFeaturesDialog";
19
+ import AddOrEditPartDialog from "./helperComponents/AddOrEditPartDialog";
20
+ import AddOrEditFeatureDialog from "./helperComponents/AddOrEditFeatureDialog";
21
+ import AddOrEditPrimerDialog from "./helperComponents/AddOrEditPrimerDialog";
22
+
23
+ const Dialogs = {
24
+ RenameSequenceDialog,
25
+ PrintDialog,
26
+ MultipleSeqsDetectedOnImportDialog,
27
+ RemoveDuplicates,
28
+ GoToDialog,
29
+ SelectDialog,
30
+ EnzymesDialog,
31
+ CreateCustomEnzyme,
32
+ AdditionalCutsiteInfoDialog,
33
+ CompareEnzymeGroupsDialog,
34
+ AlignmentToolDialog,
35
+ MergeFeaturesDialog,
36
+ AddOrEditPartDialog,
37
+ AddOrEditFeatureDialog,
38
+ AddOrEditPrimerDialog
39
+ };
40
+
41
+ export function GlobalDialog(props) {
42
+ const { dialogOverrides = {}, editorName } = props;
43
+ const [uniqKey, setUniqKeyToForceRerender] = useState();
44
+ useEffect(() => {
45
+ //on unmount, clear the global dialog state..
46
+ return () => {
47
+ hideDialog();
48
+ };
49
+ }, []);
50
+ if (
51
+ dialogHolder.editorName &&
52
+ editorName &&
53
+ dialogHolder.editorName !== editorName
54
+ ) {
55
+ return null;
56
+ }
57
+ dialogHolder.setUniqKeyToForceRerender = setUniqKeyToForceRerender;
58
+ const Comp =
59
+ dialogHolder.CustomModalComponent ||
60
+ dialogOverrides[dialogHolder.overrideName] ||
61
+ Dialogs[dialogHolder.dialogType];
62
+ if (!Comp) return null;
63
+
64
+ return (
65
+ <Comp
66
+ key={uniqKey}
67
+ hideDialog={hideDialog}
68
+ hideModal={hideDialog}
69
+ {...props}
70
+ {...dialogHolder.props}
71
+ ></Comp>
72
+ );
73
+ }
@@ -0,0 +1,110 @@
1
+ import shortid from "shortid";
2
+
3
+ import { cloneDeep, startCase } from "lodash-es";
4
+ import { convertRangeTo1Based } from "@teselagen/range-utils";
5
+
6
+ export const dialogHolder = {};
7
+ //if an overrideName is passed, then that dialog can be overridden if an overriding dialog is passed as a prop to the <Editor/>
8
+ export function showDialog({
9
+ ModalComponent,
10
+ dialogType,
11
+ props,
12
+ overrideName
13
+ }) {
14
+ dialogHolder.dialogType = dialogType;
15
+ if (!dialogHolder.dialogType && ModalComponent) {
16
+ dialogHolder.dialogType = "TGCustomModal";
17
+ }
18
+ // check if focused element in the dom is within a given editor and add an editor prop to the dialog
19
+ if (document.activeElement && document.activeElement.closest(".veEditor")) {
20
+ let editorName;
21
+ document.activeElement
22
+ .closest(".veEditor")
23
+ ?.className.split(" ")
24
+ .forEach(c => {
25
+ if (!c.trim()) return;
26
+ if (
27
+ !c.trim().includes("veEditor") &&
28
+ !c.trim().includes("previewModeFullscreen")
29
+ ) {
30
+ editorName = c;
31
+ }
32
+ });
33
+ dialogHolder.editorName = editorName;
34
+ }
35
+
36
+ dialogHolder.CustomModalComponent = ModalComponent;
37
+ dialogHolder.props = props;
38
+ dialogHolder.overrideName = overrideName;
39
+ dialogHolder.setUniqKeyToForceRerender(shortid());
40
+ }
41
+ export function hideDialog() {
42
+ delete dialogHolder.dialogType;
43
+ delete dialogHolder.CustomModalComponent;
44
+ delete dialogHolder.props;
45
+ delete dialogHolder.overrideName;
46
+ delete dialogHolder.editorName;
47
+ dialogHolder.setUniqKeyToForceRerender();
48
+ }
49
+
50
+ const typeToDialogType = {
51
+ part: "AddOrEditPartDialog",
52
+ feature: "AddOrEditFeatureDialog",
53
+ primer: "AddOrEditPrimerDialog"
54
+ };
55
+
56
+ export function showAddOrEditAnnotationDialog({
57
+ type,
58
+ annotation: _annotation
59
+ }) {
60
+ // AddOrEditPartDialog
61
+ // AddOrEditFeatureDialog
62
+ // AddOrEditPrimerDialog
63
+ const dialogType = typeToDialogType[type];
64
+ if (Object.values(typeToDialogType).includes(dialogHolder.dialogType)) {
65
+ return;
66
+ }
67
+ const nameUpper = startCase(type);
68
+ const annotation = cloneDeep(_annotation);
69
+ if (_annotation.isWrappedAddon) {
70
+ delete annotation.isWrappedAddon;
71
+ delete annotation.rangeTypeOverride;
72
+ annotation.start = _annotation.end + 1;
73
+ annotation.end = _annotation.start - 1;
74
+ }
75
+ const forward =
76
+ annotation.strand === -1
77
+ ? false
78
+ : annotation.forward !== undefined
79
+ ? !!annotation.forward
80
+ : true;
81
+ showDialog({
82
+ overrideName: `AddOrEdit${nameUpper}DialogOverride`,
83
+ dialogType,
84
+ props: {
85
+ ...(annotation.isEditLocked && {
86
+ readOnly:
87
+ typeof annotation.isEditLocked === "string"
88
+ ? annotation.isEditLocked
89
+ : "This annotation is locked"
90
+ }),
91
+ dialogProps: {
92
+ title:
93
+ annotation && annotation.id ? `Edit ${nameUpper}` : `New ${nameUpper}`
94
+ },
95
+ initialValues: {
96
+ ...(annotation
97
+ ? {
98
+ ...convertRangeTo1Based(annotation),
99
+ forward,
100
+ arrowheadType:
101
+ annotation.arrowheadType || (!forward ? "BOTTOM" : "TOP"),
102
+ ...(annotation.locations && {
103
+ locations: annotation.locations.map(convertRangeTo1Based)
104
+ })
105
+ }
106
+ : {})
107
+ }
108
+ }
109
+ });
110
+ }
package/GoToDialog.js ADDED
@@ -0,0 +1,25 @@
1
+ import createSimpleDialog from "./createSimpleDialog";
2
+ import { NumericInputField } from "@teselagen/ui";
3
+ import { get } from "lodash-es";
4
+ import { tryToRefocusEditor } from "../utils/editorUtils";
5
+
6
+ export default createSimpleDialog({
7
+ formName: "goToDialog",
8
+ fields: [
9
+ {
10
+ name: "sequencePosition",
11
+ component: NumericInputField,
12
+ validate: (val, vals, props) => {
13
+ const { min, max } = get(props, "extraProps.sequencePosition", {});
14
+ return (min && val < min) || (max && val > max)
15
+ ? "Invalid position"
16
+ : undefined;
17
+ }
18
+ }
19
+ ],
20
+ withDialogProps: {
21
+ title: "Go To",
22
+ height: 190,
23
+ onCloseHook: tryToRefocusEditor
24
+ }
25
+ });
@@ -0,0 +1,35 @@
1
+ import React, { useRef } from "react";
2
+ export function HorizontalPanelDragHandle({ onDrag }) {
3
+ const xStart = useRef(0);
4
+
5
+ const resize = useRef(e => {
6
+ const dx = xStart.current - e.clientX;
7
+ onDrag({ dx });
8
+ xStart.current = e.clientX;
9
+ });
10
+ const mouseup = useRef(() => {
11
+ document.removeEventListener("mousemove", resize.current, false);
12
+ document.removeEventListener("mousemove", mouseup.current, false);
13
+ });
14
+
15
+ return (
16
+ <div
17
+ onMouseDown={e => {
18
+ xStart.current = e.clientX;
19
+ document.addEventListener("mousemove", resize.current, false);
20
+ document.addEventListener("mouseup", mouseup.current, false);
21
+ }}
22
+ style={{
23
+ position: "absolute",
24
+ top: 0,
25
+ right: -1,
26
+ zIndex: 1000,
27
+ height: "100%",
28
+ cursor: "ew-resize",
29
+ width: 3,
30
+ opacity: 0,
31
+ background: "blue"
32
+ }}
33
+ ></div>
34
+ );
35
+ }