@teselagen/ove 0.7.26 → 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 +8 -7
  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,599 @@
1
+ import { compose } from "recompose";
2
+ import { wrapDialog, DropdownButton } from "@teselagen/ui";
3
+ import React from "react";
4
+ import { Classes, Icon, Menu, MenuItem, Tag } from "@blueprintjs/core";
5
+ import withEditorProps from "../withEditorProps";
6
+ import specialCutsiteFilterOptions from "../constants/specialCutsiteFilterOptions";
7
+ import {
8
+ differenceBy,
9
+ find,
10
+ flatMap,
11
+ forEach,
12
+ intersectionBy,
13
+ map,
14
+ noop,
15
+ sortBy
16
+ } from "lodash-es";
17
+ import SingleEnzymeCutsiteInfo from "../helperComponents/PropertiesDialog/SingleEnzymeCutsiteInfo";
18
+ import { showDialog } from "../GlobalDialogUtils";
19
+
20
+ import {
21
+ aliasedEnzymesByName,
22
+ cutSequenceByRestrictionEnzyme,
23
+ defaultEnzymesByName
24
+ } from "@teselagen/sequence-utils";
25
+ import { withRestrictionEnzymes } from "./withRestrictionEnzymes";
26
+ import { getEnzymeAliases } from "../utils/editorUtils";
27
+
28
+ function getUserEnzymeGroups(p) {
29
+ return p.enzymeGroupsOverride || window.getExistingEnzymeGroups();
30
+ }
31
+
32
+ function isGroup({ cutsiteOrGroupKey }) {
33
+ const isUserCreatedGroup = cutsiteOrGroupKey.startsWith("__userCreatedGroup");
34
+ const specialCutsiteFilterOption =
35
+ specialCutsiteFilterOptions[cutsiteOrGroupKey];
36
+ return isUserCreatedGroup || specialCutsiteFilterOption;
37
+ }
38
+
39
+ export const AdditionalCutsiteInfoDialog = compose(
40
+ withEditorProps,
41
+ withRestrictionEnzymes,
42
+ wrapDialog({
43
+ isDraggable: true,
44
+ getDialogProps: props => {
45
+ if (isGroup(props)) {
46
+ return {
47
+ title: (
48
+ <div style={{ display: "flex" }}>
49
+ Group - &nbsp;
50
+ {getGroupElAndCutsites(props).title}
51
+ </div>
52
+ )
53
+ };
54
+ } else {
55
+ let c = props.allCutsites.cutsitesByName;
56
+ const name = props.cutsiteOrGroupKey.toLowerCase();
57
+ if (!c[name]) {
58
+ const e = aliasedEnzymesByName[name];
59
+ if (e) {
60
+ const res = cutSequenceByRestrictionEnzyme(
61
+ props.sequenceData.sequence,
62
+ true,
63
+ e
64
+ );
65
+ c = { ...c, [name]: res };
66
+ }
67
+ }
68
+ return {
69
+ title: (
70
+ <div style={{ display: "flex" }}>
71
+ Enzyme - &nbsp;
72
+ <CutsiteTag
73
+ noClick
74
+ showActiveText
75
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
76
+ cutsitesByNameActive={props.filteredCutsites.cutsitesByName}
77
+ cutsitesByName={c}
78
+ name={props.cutsiteOrGroupKey}
79
+ ></CutsiteTag>
80
+ </div>
81
+ )
82
+ };
83
+ }
84
+ }
85
+ })
86
+ )(function (props) {
87
+ const {
88
+ dispatch,
89
+ editorName,
90
+ cutsiteOrGroupKey,
91
+ allCutsites: { cutsitesByName },
92
+ filteredCutsites: { cutsitesByName: cutsitesByNameActive },
93
+ selectedAnnotationId,
94
+ allRestrictionEnzymes
95
+ } = props;
96
+
97
+ let inner;
98
+
99
+ const userEnzymeGroups = getUserEnzymeGroups(props);
100
+ if (isGroup(props)) {
101
+ //group case
102
+ const ret = getGroupElAndCutsites(props);
103
+ const enzymesThatCutInSeq = ret.enzymesThatCutInSeq;
104
+ const enzymesThatDontCutInSeq = ret.enzymesThatDontCutInSeq;
105
+ inner = (
106
+ <div>
107
+ <div>
108
+ <DropdownButton
109
+ minimal
110
+ menu={
111
+ <Menu>
112
+ {flatMap(
113
+ [
114
+ ...map(specialCutsiteFilterOptions),
115
+ ...map(userEnzymeGroups, (v, key) => ({
116
+ label: key,
117
+ value: "__userCreatedGroup" + key
118
+ }))
119
+ ],
120
+ ({ label, value }, key, i) => {
121
+ if (value === cutsiteOrGroupKey) return [];
122
+ return (
123
+ <MenuItem
124
+ onClick={() => {
125
+ showDialog({
126
+ dialogType: "CompareEnzymeGroupsDialog",
127
+ props: {
128
+ dialogProps: {
129
+ title: "Comparing Groups",
130
+ width: 450
131
+ },
132
+ group1: cutsiteOrGroupKey,
133
+ group2: value
134
+ }
135
+ });
136
+ }}
137
+ key={i}
138
+ text={`vs ${label}`}
139
+ ></MenuItem>
140
+ );
141
+ }
142
+ )}
143
+ </Menu>
144
+ }
145
+ text="Compare.."
146
+ ></DropdownButton>
147
+ <br></br>
148
+ <br></br>
149
+ </div>
150
+
151
+ <div style={{ display: "flex", justifyContent: "space-between" }}>
152
+ {!!enzymesThatCutInSeq.length && (
153
+ <div>
154
+ <div
155
+ style={{
156
+ display: "flex",
157
+ flexDirection: "column",
158
+ overflow: "auto"
159
+ // maxHeight: 400
160
+ }}
161
+ >
162
+ {enzymesThatCutInSeq.map((e, i) => (
163
+ <CutsiteTag
164
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
165
+ cutsitesByName={props.allCutsites.cutsitesByName}
166
+ cutsitesByNameActive={cutsitesByNameActive}
167
+ key={i}
168
+ {...e}
169
+ ></CutsiteTag>
170
+ ))}
171
+ </div>
172
+ </div>
173
+ )}
174
+ {enzymesThatDontCutInSeq && (
175
+ <div>
176
+ <div
177
+ style={{
178
+ display: "flex",
179
+ flexDirection: "column",
180
+ overflow: "auto"
181
+ }}
182
+ >
183
+ {enzymesThatDontCutInSeq.map((e, i) => (
184
+ <CutsiteTag
185
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
186
+ cutsitesByName={props.allCutsites.cutsitesByName}
187
+ cutsitesByNameActive={cutsitesByNameActive}
188
+ key={i}
189
+ {...e}
190
+ ></CutsiteTag>
191
+ ))}
192
+ </div>
193
+ </div>
194
+ )}
195
+ </div>
196
+ </div>
197
+ );
198
+ } else if (
199
+ //single enzyme case
200
+ cutsitesByName[cutsiteOrGroupKey.toLowerCase()] ||
201
+ allRestrictionEnzymes[cutsiteOrGroupKey.toLowerCase()] ||
202
+ aliasedEnzymesByName[cutsiteOrGroupKey.toLowerCase()]
203
+ ) {
204
+ const inTheseUserGroups = [];
205
+ const cutsiteGroup = cutsitesByName[cutsiteOrGroupKey.toLowerCase()] || [];
206
+ const enzyme = cutsiteGroup[0]
207
+ ? cutsiteGroup[0].restrictionEnzyme
208
+ : allRestrictionEnzymes[cutsiteOrGroupKey.toLowerCase()] ||
209
+ aliasedEnzymesByName[cutsiteOrGroupKey.toLowerCase()];
210
+
211
+ if (cutsiteGroup.length && cutsiteGroup.length <= 3) {
212
+ const { el } = getGroupElAndCutsites({
213
+ ...props,
214
+ cutsiteOrGroupKey: find(
215
+ specialCutsiteFilterOptions,
216
+ ({ cutsThisManyTimes }) => cutsThisManyTimes === cutsiteGroup.length
217
+ ).value
218
+ });
219
+
220
+ inTheseUserGroups.push(el);
221
+ }
222
+
223
+ const enzymeName = enzyme.name;
224
+
225
+ forEach(userEnzymeGroups, (nameArray, name) => {
226
+ let isInGroup;
227
+ forEach(nameArray, n => {
228
+ if (n.toLowerCase() === enzymeName.toLowerCase()) {
229
+ isInGroup = true;
230
+ }
231
+ });
232
+ if (isInGroup) {
233
+ const cutsiteOrGroupKey = "__userCreatedGroup" + name;
234
+
235
+ const { el } = getGroupElAndCutsites({
236
+ ...props,
237
+ cutsiteOrGroupKey
238
+ });
239
+
240
+ inTheseUserGroups.push(el);
241
+ }
242
+ });
243
+ inner = (
244
+ <div>
245
+ {!!inTheseUserGroups.length && (
246
+ <div style={{ marginBottom: 20 }}>{inTheseUserGroups}</div>
247
+ )}
248
+ <SingleEnzymeCutsiteInfo
249
+ {...{
250
+ dispatch,
251
+ editorName,
252
+ selectedAnnotationId,
253
+ cutsiteGroup,
254
+ enzyme,
255
+ allRestrictionEnzymes,
256
+ allCutsites: props.allCutsites,
257
+ filteredCutsites: props.filteredCutsites
258
+ }}
259
+ ></SingleEnzymeCutsiteInfo>
260
+ </div>
261
+ );
262
+ } else {
263
+ console.error(`we shouldn't be here!:`, cutsiteOrGroupKey);
264
+ return null;
265
+ }
266
+
267
+ return <div className={Classes.DIALOG_BODY}>{inner}</div>;
268
+ });
269
+
270
+ export const CompareEnzymeGroupsDialog = compose(
271
+ withEditorProps,
272
+ withRestrictionEnzymes,
273
+ wrapDialog({
274
+ isDraggable: true
275
+ })
276
+ )(function (props) {
277
+ const {
278
+ group1,
279
+ group2,
280
+ filteredCutsites: { cutsitesByName: cutsitesByNameActive }
281
+ } = props;
282
+
283
+ const g1 = getGroupElAndCutsites({
284
+ ...props,
285
+ cutsiteOrGroupKey: group1
286
+ });
287
+
288
+ const g2 = getGroupElAndCutsites({
289
+ ...props,
290
+ cutsiteOrGroupKey: group2
291
+ });
292
+ const byNameLower = n => n.name.toLowerCase();
293
+ const shared = intersectionBy(
294
+ g1.allEnzymesInGroup,
295
+ g2.allEnzymesInGroup,
296
+ byNameLower
297
+ );
298
+
299
+ const g1Only = differenceBy(g1.allEnzymesInGroup, shared, byNameLower);
300
+ const g2Only = differenceBy(g2.allEnzymesInGroup, shared, byNameLower);
301
+ return (
302
+ <div
303
+ style={{ display: "flex", justifyContent: "space-between" }}
304
+ className={Classes.DIALOG_BODY}
305
+ >
306
+ <Column
307
+ dataTest="tg-column-1"
308
+ title="In"
309
+ header={g1.el}
310
+ body={g1Only.map((e, i) => {
311
+ return (
312
+ <CutsiteTag
313
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
314
+ cutsitesByName={props.allCutsites.cutsitesByName}
315
+ cutsitesByNameActive={cutsitesByNameActive}
316
+ key={i}
317
+ {...e}
318
+ ></CutsiteTag>
319
+ );
320
+ })}
321
+ />
322
+
323
+ <Column
324
+ dataTest="tg-column-2"
325
+ title="In Both"
326
+ header={
327
+ <div>
328
+ {g1.el} {g2.el}
329
+ </div>
330
+ }
331
+ body={shared.map((e, i) => {
332
+ return (
333
+ <CutsiteTag
334
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
335
+ cutsitesByName={props.allCutsites.cutsitesByName}
336
+ cutsitesByNameActive={cutsitesByNameActive}
337
+ key={i}
338
+ {...e}
339
+ ></CutsiteTag>
340
+ );
341
+ })}
342
+ />
343
+
344
+ <Column
345
+ dataTest="tg-column-3"
346
+ title="In"
347
+ header={g2.el}
348
+ body={g2Only.map((e, i) => {
349
+ return (
350
+ <CutsiteTag
351
+ allRestrictionEnzymes={props.allRestrictionEnzymes}
352
+ cutsitesByName={props.allCutsites.cutsitesByName}
353
+ cutsitesByNameActive={cutsitesByNameActive}
354
+ key={i}
355
+ {...e}
356
+ ></CutsiteTag>
357
+ );
358
+ })}
359
+ />
360
+ </div>
361
+ );
362
+ });
363
+
364
+ function isUserEnzymeGroup(group) {
365
+ const isUserCreatedGroup = group.startsWith("__userCreatedGroup");
366
+ return isUserCreatedGroup;
367
+ }
368
+
369
+ const getGroupElAndCutsites = ({
370
+ enzymeGroupsOverride,
371
+ cutsiteOrGroupKey,
372
+ filteredRestrictionEnzymes,
373
+ allCutsites
374
+ }) => {
375
+ const userEnzymeGroups =
376
+ enzymeGroupsOverride || window.getExistingEnzymeGroups();
377
+
378
+ let isGroupActive;
379
+ let label;
380
+
381
+ const enzymesThatDontCutInSeq = [];
382
+ let enzymesThatCutInSeq = [];
383
+ forEach(filteredRestrictionEnzymes, g => {
384
+ if (g.value === cutsiteOrGroupKey) {
385
+ isGroupActive = true;
386
+ }
387
+ });
388
+
389
+ if (cutsiteOrGroupKey === "type2s") {
390
+ const nameArray = flatMap(defaultEnzymesByName, e =>
391
+ e.isType2S ? e.name : []
392
+ );
393
+ label = "Type IIS Enzymes";
394
+
395
+ sortBy(nameArray).forEach(name => {
396
+ const cutsites = allCutsites.cutsitesByName[name.toLowerCase()];
397
+ if (!cutsites) {
398
+ enzymesThatDontCutInSeq.push({ name, sites: [] });
399
+ } else {
400
+ enzymesThatCutInSeq.push({ name, sites: cutsites });
401
+ }
402
+ });
403
+ } else if (isUserEnzymeGroup(cutsiteOrGroupKey)) {
404
+ const name = cutsiteOrGroupKey.replace("__userCreatedGroup", "");
405
+ const nameArray = userEnzymeGroups[name];
406
+ label = getUserGroupLabel({ name, nameArray });
407
+
408
+ sortBy(nameArray).forEach(name => {
409
+ const cutsites = allCutsites.cutsitesByName[name.toLowerCase()];
410
+ if (!cutsites) {
411
+ enzymesThatDontCutInSeq.push({ name, sites: [] });
412
+ } else {
413
+ enzymesThatCutInSeq.push({ name, sites: cutsites });
414
+ }
415
+ });
416
+ } else {
417
+ //it's a single/double/etc
418
+ const specialCutsiteFilterOption =
419
+ specialCutsiteFilterOptions[cutsiteOrGroupKey];
420
+ label = specialCutsiteFilterOption.label;
421
+ enzymesThatCutInSeq = map(allCutsites.cutsitesByName, cutsites =>
422
+ cutsites.length === specialCutsiteFilterOption.cutsThisManyTimes
423
+ ? { name: cutsites[0].name, sites: cutsites }
424
+ : null
425
+ ).filter(n => n !== null);
426
+ }
427
+ const title = (
428
+ <div style={{ display: "flex" }}>
429
+ {label} &nbsp;
430
+ {isGroupActive ? "" : "(inactive)"}
431
+ </div>
432
+ );
433
+ const el = addCutsiteGroupClickHandler({
434
+ cutsiteOrGroupKey,
435
+ el: (
436
+ <Tag minimal intent={isGroupActive && "primary"} style={{ margin: 3 }}>
437
+ {label}
438
+ </Tag>
439
+ ),
440
+ title
441
+ });
442
+
443
+ return {
444
+ el,
445
+ title,
446
+ enzymesThatDontCutInSeq,
447
+ enzymesThatCutInSeq,
448
+ allEnzymesInGroup: [...enzymesThatCutInSeq, ...enzymesThatDontCutInSeq]
449
+ // cutsitesInGroup: [] //tnrtodo
450
+ };
451
+ };
452
+
453
+ export const CutsiteTag = ({
454
+ allRestrictionEnzymes,
455
+ showActiveText,
456
+ cutsitesByNameActive,
457
+ cutsitesByName,
458
+ name,
459
+ onWrapperClick,
460
+ doNotShowCuts,
461
+ noClick,
462
+ forceOpenCutsiteInfo
463
+ }) => {
464
+ const isHidden = getIsEnzymeHidden({ name, allRestrictionEnzymes });
465
+
466
+ let numCuts = (cutsitesByName[name.toLowerCase()] || []).length;
467
+
468
+ const aliases = getEnzymeAliases(name);
469
+ aliases.forEach(alias => {
470
+ if (numCuts === 0) {
471
+ numCuts = (cutsitesByName[alias.toLowerCase()] || []).length;
472
+ }
473
+ });
474
+ const isActive = numCuts
475
+ ? cutsitesByNameActive[name.toLowerCase()]
476
+ ? "primary"
477
+ : undefined
478
+ : undefined;
479
+
480
+ const el = (
481
+ <Tag
482
+ onClick={onWrapperClick}
483
+ intent={isActive}
484
+ style={{ margin: 3, opacity: isHidden ? 0.5 : 1 }}
485
+ >
486
+ <div style={{ display: "flex" }}>
487
+ {getCutsiteWithNumCuts({
488
+ name,
489
+ numCuts,
490
+ doNotShowCuts
491
+ })}
492
+ {showActiveText ? (
493
+ isHidden ? (
494
+ <span>&nbsp; hidden</span>
495
+ ) : isActive ? (
496
+ <span>&nbsp; active</span>
497
+ ) : (
498
+ <span>&nbsp; inactive</span>
499
+ )
500
+ ) : null}
501
+ </div>
502
+ </Tag>
503
+ );
504
+
505
+ return addCutsiteGroupClickHandler({
506
+ el,
507
+ noClick,
508
+ cutsiteOrGroupKey: name,
509
+ forceOpenCutsiteInfo
510
+ });
511
+ };
512
+
513
+ export const getUserGroupLabel = ({ name, nameArray }) => (
514
+ <span
515
+ style={{ display: "flex", alignItems: "center" }}
516
+ title={`User created enzyme group ${name} -- ${nameArray.join(" ")}`}
517
+ >
518
+ <Icon size={10} icon="user"></Icon>&nbsp;{name}
519
+ </span>
520
+ );
521
+
522
+ export const getCutsiteWithNumCuts = ({ name, numCuts, doNotShowCuts }) => {
523
+ return (
524
+ <div
525
+ style={{
526
+ display: "flex",
527
+ alignItems: "center",
528
+ justifyContent: "space-between"
529
+ }}
530
+ >
531
+ {" "}
532
+ <div>{name}</div>{" "}
533
+ {!doNotShowCuts && (
534
+ <div style={{ fontSize: 12 }}>
535
+ &nbsp;({numCuts} cut{numCuts === 1 ? "" : "s"})
536
+ </div>
537
+ )}
538
+ </div>
539
+ );
540
+ };
541
+
542
+ export const addCutsiteGroupClickHandler = ({
543
+ closeDropDown = noop,
544
+ cutsiteOrGroupKey,
545
+ el,
546
+ noClick,
547
+ forceOpenCutsiteInfo
548
+ }) => (
549
+ <div
550
+ className={noClick ? "tg-cutsite-label" : "tg-clickable-cutsite-label"}
551
+ style={noClick ? {} : { cursor: "pointer" }}
552
+ onClick={
553
+ noClick
554
+ ? undefined
555
+ : e => {
556
+ const isInMultiSelect = e.target.closest(
557
+ ".bp3-multi-select-popover"
558
+ );
559
+ if (!forceOpenCutsiteInfo && isInMultiSelect) return true;
560
+ closeDropDown();
561
+ showDialog({
562
+ dialogType: "AdditionalCutsiteInfoDialog",
563
+ props: {
564
+ cutsiteOrGroupKey
565
+ }
566
+ });
567
+ }
568
+ }
569
+ >
570
+ {el}
571
+ </div>
572
+ );
573
+
574
+ function Column({ dataTest, header, body, title }) {
575
+ return (
576
+ <div data-test={dataTest} style={{ flexGrow: "1", flexBasis: "0" }}>
577
+ {title}:
578
+ <div
579
+ style={{
580
+ height: 60,
581
+
582
+ marginBottom: 20,
583
+ borderBottom: "1px solid lightgrey"
584
+ }}
585
+ >
586
+ {header}
587
+ </div>
588
+ {body}
589
+ </div>
590
+ );
591
+ }
592
+
593
+ function getIsEnzymeHidden({ name, allRestrictionEnzymes }) {
594
+ let isHidden = true;
595
+ if (allRestrictionEnzymes[name.toLowerCase()]) {
596
+ isHidden = false;
597
+ }
598
+ return isHidden;
599
+ }
@@ -1,9 +1,9 @@
1
1
  import { default as React } from '../../../../node_modules/react';
2
2
  declare const _default: import('../../../../node_modules/react-redux').ConnectedComponent<typeof Mismatches, {
3
- context?: React.Context<import('../../../../node_modules/react-redux').ReactReduxContextValue<any, import('../../../../node_modules/redux').AnyAction>> | undefined;
4
- store?: import('../../../../node_modules/redux').Store<any, import('../../../../node_modules/redux').AnyAction> | undefined;
3
+ context?: import('../../../../node_modules/react-redux/es/components/Context').ReactReduxContextInstance | undefined;
4
+ store?: import('../../../../node_modules/redux').Store | undefined;
5
5
  } | {
6
- store?: import('../../../../node_modules/redux').Store<any, import('../../../../node_modules/redux').AnyAction> | undefined;
6
+ store?: import('../../../../node_modules/redux').Store | undefined;
7
7
  }>;
8
8
  export default _default;
9
9
  declare class Mismatches extends React.Component<any, any, any> {
@@ -0,0 +1,105 @@
1
+ import {
2
+ Button,
3
+ Popover,
4
+ Intent,
5
+ Tooltip,
6
+ Tag,
7
+ Menu,
8
+ MenuItem
9
+ } from "@blueprintjs/core";
10
+ import React from "react";
11
+ import { map, startCase } from "lodash-es";
12
+ import pureNoFunc from "../utils/pureNoFunc";
13
+ // import { fullSequenceTranslationMenu } from "../MenuBar/viewSubmenu";
14
+
15
+ export default pureNoFunc(function AlignmentVisibilityTool(props) {
16
+ return (
17
+ <Popover
18
+ minimal
19
+ position="bottom"
20
+ content={<VisibilityOptions {...props} />}
21
+ target={
22
+ <Tooltip content="Visibility Options">
23
+ <Button
24
+ className="tg-alignment-visibility-toggle"
25
+ small
26
+ rightIcon="caret-down"
27
+ intent={Intent.PRIMARY}
28
+ minimal
29
+ icon="eye-open"
30
+ />
31
+ </Tooltip>
32
+ }
33
+ />
34
+ );
35
+ });
36
+
37
+ function VisibilityOptions({
38
+ // alignmentAnnotationVisibility = {},
39
+ alignmentAnnotationVisibilityToggle,
40
+ togglableAlignmentAnnotationSettings = {},
41
+ // alignmentAnnotationLabelVisibility = {},
42
+ // alignmentAnnotationLabelVisibilityToggle
43
+ annotationsWithCounts,
44
+ currentPairwiseAlignmentIndex
45
+ }) {
46
+ let annotationCountToUse = {};
47
+ if (currentPairwiseAlignmentIndex) {
48
+ annotationCountToUse = annotationsWithCounts[currentPairwiseAlignmentIndex];
49
+ } else {
50
+ annotationCountToUse = annotationsWithCounts[0];
51
+ }
52
+ return (
53
+ <Menu
54
+ style={{ padding: 10 }}
55
+ className="alignmentAnnotationVisibilityToolInner"
56
+ >
57
+ {map(togglableAlignmentAnnotationSettings, (visible, annotationName) => {
58
+ return (
59
+ <MenuItem
60
+ icon={visible ? "tick" : ""}
61
+ onClick={e => {
62
+ e.stopPropagation();
63
+ if (annotationName === "axis") {
64
+ return alignmentAnnotationVisibilityToggle({
65
+ axisNumbers: !visible,
66
+ axis: !visible
67
+ });
68
+ }
69
+ if (annotationName === "cdsFeatureTranslations" && !visible) {
70
+ return alignmentAnnotationVisibilityToggle({
71
+ cdsFeatureTranslations: !visible,
72
+ translations: !visible
73
+ });
74
+ }
75
+
76
+ alignmentAnnotationVisibilityToggle({
77
+ [annotationName]: !visible
78
+ });
79
+ }}
80
+ text={
81
+ <>
82
+ {startCase(annotationName)
83
+ .replace("Cds", "CDS")
84
+ .replace("Dna", "DNA")}
85
+ {annotationName in annotationCountToUse ? (
86
+ <Tag round style={{ marginLeft: 7 }}>
87
+ {annotationCountToUse[annotationName]}
88
+ </Tag>
89
+ ) : (
90
+ ""
91
+ )}
92
+ </>
93
+ }
94
+ key={annotationName}
95
+ ></MenuItem>
96
+ );
97
+ })}
98
+ {/* <MenuItem icon="" text={fullSequenceTranslationMenu.text}>
99
+ {fullSequenceTranslationMenu.submenu.map(({ text, cmd }) => {
100
+ return <MenuItem key={cmd} text={text}></MenuItem>;
101
+ })}
102
+ </MenuItem> */}
103
+ </Menu>
104
+ );
105
+ }