@teselagen/ove 0.7.3-beta.7 → 0.7.4
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/AlignmentView/index.d.ts +4 -0
- package/DigestTool/DigestTool.d.ts +1 -1
- package/helperComponents/PropertiesDialog/index.d.ts +2 -7
- package/index.cjs.js +7219 -581
- package/index.es.js +7208 -570
- package/index.umd.js +7216 -560
- package/package.json +3 -2
- package/src/AlignmentView/index.js +45 -83
- package/src/CreateAnnotationsPage.js +1 -1
- package/src/DigestTool/DigestTool.js +78 -75
- package/src/GlobalDialogUtils.js +1 -0
- package/src/helperComponents/PropertiesDialog/CutsiteProperties.js +126 -135
- package/src/helperComponents/PropertiesDialog/SingleEnzymeCutsiteInfo.js +59 -51
- package/src/helperComponents/PropertiesDialog/index.js +115 -114
- package/src/helperComponents/RemoveDuplicates/index.js +144 -160
- package/src/utils/useFormValue.js +7 -0
- package/src/withEditorInteractions/index.js +18 -20
- package/utils/useFormValue.d.ts +1 -0
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
withSelectedEntities,
|
|
5
|
-
createCommandMenu
|
|
6
|
-
} from "@teselagen/ui";
|
|
7
|
-
import { map, get } from "lodash-es";
|
|
1
|
+
import React, { useCallback, useMemo } from "react";
|
|
2
|
+
import { DataTable, createCommandMenu } from "@teselagen/ui";
|
|
3
|
+
import { get } from "lodash-es";
|
|
8
4
|
import CutsiteFilter from "../../CutsiteFilter";
|
|
9
5
|
import { Button, ButtonGroup } from "@blueprintjs/core";
|
|
10
6
|
import { connectToEditor } from "../../withEditorProps";
|
|
11
7
|
import { compose } from "recompose";
|
|
12
8
|
import selectors from "../../selectors";
|
|
13
|
-
import
|
|
9
|
+
import _commands from "../../commands";
|
|
14
10
|
import { userDefinedHandlersAndOpts } from "../../Editor/userDefinedHandlersAndOpts";
|
|
15
11
|
import { pick } from "lodash-es";
|
|
16
12
|
import SingleEnzymeCutsiteInfo from "./SingleEnzymeCutsiteInfo";
|
|
@@ -18,105 +14,107 @@ import { withRestrictionEnzymes } from "../../CutsiteFilter/withRestrictionEnzym
|
|
|
18
14
|
import { cutsitesSubmenu } from "../../MenuBar/viewSubmenu";
|
|
19
15
|
import { getVisFilter } from "./GenericAnnotationProperties";
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
const schema = {
|
|
18
|
+
fields: [
|
|
19
|
+
{ path: "name", type: "string" },
|
|
20
|
+
{ path: "numberOfCuts", type: "number" },
|
|
21
|
+
{ path: "groups", type: "string" }
|
|
22
|
+
]
|
|
23
|
+
};
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<SingleEnzymeCutsiteInfo
|
|
30
|
-
{...{
|
|
31
|
-
allRestrictionEnzymes: this.props.allRestrictionEnzymes,
|
|
32
|
-
allCutsites: this.props.allCutsites,
|
|
33
|
-
filteredCutsites: this.props.filteredCutsites,
|
|
34
|
-
editorName: this.props.editorName,
|
|
35
|
-
dispatch: this.props.dispatch,
|
|
36
|
-
selectedAnnotationId: this.props.selectedAnnotationId,
|
|
37
|
-
cutsiteGroup: row.original.cutsiteGroup,
|
|
38
|
-
enzyme: row.original.enzyme
|
|
39
|
-
}}
|
|
40
|
-
></SingleEnzymeCutsiteInfo>
|
|
41
|
-
);
|
|
42
|
-
};
|
|
25
|
+
const defaultValues = { order: ["numberOfCuts"] };
|
|
43
26
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
27
|
+
const CutsiteProperties = props => {
|
|
28
|
+
const commands = _commands({ props });
|
|
29
|
+
const {
|
|
30
|
+
allRestrictionEnzymes,
|
|
31
|
+
allCutsites,
|
|
32
|
+
annotationVisibilityShow,
|
|
33
|
+
createNewDigest,
|
|
34
|
+
dispatch,
|
|
35
|
+
editorName,
|
|
36
|
+
filteredCutsites,
|
|
37
|
+
selectedAnnotationId
|
|
38
|
+
} = props;
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
const SubComponent = useCallback(
|
|
41
|
+
row => (
|
|
42
|
+
<SingleEnzymeCutsiteInfo
|
|
43
|
+
allRestrictionEnzymes={allRestrictionEnzymes}
|
|
44
|
+
allCutsites={allCutsites}
|
|
45
|
+
filteredCutsites={filteredCutsites}
|
|
46
|
+
editorName={editorName}
|
|
47
|
+
dispatch={dispatch}
|
|
48
|
+
selectedAnnotationId={selectedAnnotationId}
|
|
49
|
+
cutsiteGroup={row.original.cutsiteGroup}
|
|
50
|
+
enzyme={row.original.enzyme}
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
53
|
+
[
|
|
54
|
+
allCutsites,
|
|
55
|
+
allRestrictionEnzymes,
|
|
56
|
+
dispatch,
|
|
57
57
|
editorName,
|
|
58
|
-
|
|
59
|
-
filteredCutsites: allCutsites,
|
|
58
|
+
filteredCutsites,
|
|
60
59
|
selectedAnnotationId
|
|
61
|
-
|
|
60
|
+
]
|
|
61
|
+
);
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
let groups = "";
|
|
67
|
-
const exisitingEnzymeGroups = window.getExistingEnzymeGroups();
|
|
63
|
+
const onChangeHook = useCallback(() => {
|
|
64
|
+
annotationVisibilityShow("cutsites");
|
|
65
|
+
}, [annotationVisibilityShow]);
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
if (exisitingEnzymeGroups[key].includes(name)) groups += key;
|
|
71
|
-
groups += " ";
|
|
72
|
-
});
|
|
67
|
+
const { cutsitesByName, cutsitesById } = filteredCutsites;
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
name
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
69
|
+
const cutsitesToUse = useMemo(
|
|
70
|
+
() =>
|
|
71
|
+
Object.values(cutsitesByName || {}).map(cutsiteGroup => {
|
|
72
|
+
const name = cutsiteGroup[0].restrictionEnzyme.name;
|
|
73
|
+
let groups = "";
|
|
74
|
+
const exisitingEnzymeGroups = window.getExistingEnzymeGroups();
|
|
75
|
+
|
|
76
|
+
Object.keys(exisitingEnzymeGroups).forEach(key => {
|
|
77
|
+
if (exisitingEnzymeGroups[key].includes(name)) groups += key;
|
|
78
|
+
groups += " ";
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
cutsiteGroup,
|
|
83
|
+
id: name,
|
|
84
|
+
name,
|
|
85
|
+
numberOfCuts: cutsiteGroup.length,
|
|
86
|
+
enzyme: cutsiteGroup[0].restrictionEnzyme,
|
|
87
|
+
groups
|
|
88
|
+
};
|
|
89
|
+
}),
|
|
90
|
+
[cutsitesByName]
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const selectedIds = useMemo(
|
|
94
|
+
() => get(cutsitesById[selectedAnnotationId], "restrictionEnzyme.name"),
|
|
95
|
+
[cutsitesById, selectedAnnotationId]
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<>
|
|
100
|
+
<div
|
|
101
|
+
style={{
|
|
102
|
+
marginBottom: 10,
|
|
103
|
+
paddingTop: 3,
|
|
104
|
+
display: "flex",
|
|
105
|
+
// flexWrap: 'wrap',
|
|
106
|
+
width: "100%",
|
|
107
|
+
// justifyContent: "space-between",
|
|
108
|
+
alignItems: "center"
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{getVisFilter(
|
|
112
|
+
createCommandMenu(cutsitesSubmenu, commands, {
|
|
113
|
+
useTicks: true
|
|
114
|
+
})
|
|
115
|
+
)}
|
|
116
|
+
<ButtonGroup>
|
|
98
117
|
<Button
|
|
99
|
-
style={{ marginLeft: 10, cursor: "auto" }}
|
|
100
|
-
disabled
|
|
101
|
-
minimal
|
|
102
|
-
icon="filter"
|
|
103
|
-
/> */}
|
|
104
|
-
{getVisFilter(
|
|
105
|
-
createCommandMenu(cutsitesSubmenu, this.commands, {
|
|
106
|
-
useTicks: true
|
|
107
|
-
})
|
|
108
|
-
)}
|
|
109
|
-
<ButtonGroup>
|
|
110
|
-
<Button
|
|
111
|
-
intent="success"
|
|
112
|
-
data-tip="Virtual Digest"
|
|
113
|
-
icon="cut"
|
|
114
|
-
style={{ marginLeft: 15, flexGrow: -1 }}
|
|
115
|
-
onClick={() => {
|
|
116
|
-
createNewDigest();
|
|
117
|
-
}}
|
|
118
|
-
></Button>
|
|
119
|
-
{/* <Button
|
|
120
118
|
intent="success"
|
|
121
119
|
data-tip="Virtual Digest"
|
|
122
120
|
icon="cut"
|
|
@@ -124,43 +122,37 @@ class CutsiteProperties extends React.Component {
|
|
|
124
122
|
onClick={() => {
|
|
125
123
|
createNewDigest();
|
|
126
124
|
}}
|
|
127
|
-
>
|
|
128
|
-
</Button> */}
|
|
129
|
-
</ButtonGroup>
|
|
130
|
-
|
|
131
|
-
<CutsiteFilter
|
|
132
|
-
{...pick(this.props, userDefinedHandlersAndOpts)}
|
|
133
|
-
style={{ marginLeft: "auto", marginRight: 3 }}
|
|
134
|
-
editorName={editorName}
|
|
135
|
-
manageEnzymesToLeft
|
|
136
|
-
onChangeHook={this.onChangeHook}
|
|
137
125
|
/>
|
|
138
|
-
</
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
noSelect
|
|
146
|
-
noHeader
|
|
147
|
-
noFooter
|
|
148
|
-
withExpandAndCollapseAllButton
|
|
149
|
-
noFullscreenButton
|
|
150
|
-
noPadding
|
|
151
|
-
defaults={{ order: ["numberOfCuts"] }}
|
|
152
|
-
formName="cutsiteProperties"
|
|
153
|
-
noRouter
|
|
154
|
-
withSearch={false}
|
|
155
|
-
SubComponent={this.SubComponent}
|
|
156
|
-
isInfinite
|
|
157
|
-
schema={this.schema}
|
|
158
|
-
entities={cutsitesToUse}
|
|
126
|
+
</ButtonGroup>
|
|
127
|
+
<CutsiteFilter
|
|
128
|
+
{...pick(props, userDefinedHandlersAndOpts)}
|
|
129
|
+
style={{ marginLeft: "auto", marginRight: 3 }}
|
|
130
|
+
editorName={editorName}
|
|
131
|
+
manageEnzymesToLeft
|
|
132
|
+
onChangeHook={onChangeHook}
|
|
159
133
|
/>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
134
|
+
</div>
|
|
135
|
+
<DataTable
|
|
136
|
+
selectedIds={selectedIds}
|
|
137
|
+
compact
|
|
138
|
+
noSelect
|
|
139
|
+
noHeader
|
|
140
|
+
noFooter
|
|
141
|
+
withExpandAndCollapseAllButton
|
|
142
|
+
noFullscreenButton
|
|
143
|
+
noPadding
|
|
144
|
+
defaults={defaultValues}
|
|
145
|
+
formName="cutsiteProperties"
|
|
146
|
+
noRouter
|
|
147
|
+
withSearch={false}
|
|
148
|
+
SubComponent={SubComponent}
|
|
149
|
+
isInfinite
|
|
150
|
+
schema={schema}
|
|
151
|
+
entities={cutsitesToUse}
|
|
152
|
+
/>
|
|
153
|
+
</>
|
|
154
|
+
);
|
|
155
|
+
};
|
|
164
156
|
|
|
165
157
|
export default compose(
|
|
166
158
|
connectToEditor((editorState, ownProps) => {
|
|
@@ -180,6 +172,5 @@ export default compose(
|
|
|
180
172
|
cutsites: cutsites.cutsitesArray
|
|
181
173
|
};
|
|
182
174
|
}),
|
|
183
|
-
withRestrictionEnzymes
|
|
184
|
-
withSelectedEntities("cutsiteProperties")
|
|
175
|
+
withRestrictionEnzymes
|
|
185
176
|
)(CutsiteProperties);
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useCallback, useMemo } from "react";
|
|
2
2
|
import { DataTable } from "@teselagen/ui";
|
|
3
|
-
|
|
4
3
|
import { CutsiteTag } from "../../CutsiteFilter/AdditionalCutsiteInfoDialog";
|
|
5
|
-
|
|
6
4
|
import EnzymeViewer from "../../EnzymeViewer";
|
|
7
5
|
import { getEnzymeAliases } from "../../utils/editorUtils";
|
|
8
6
|
|
|
7
|
+
const schema = {
|
|
8
|
+
fields: [
|
|
9
|
+
{ path: "topSnipPosition", displayName: "Top Snip", type: "string" },
|
|
10
|
+
{ path: "position", type: "string" },
|
|
11
|
+
{ path: "strand", type: "string" }
|
|
12
|
+
]
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
export default function SingleEnzymeCutsiteInfo({
|
|
10
16
|
cutsiteGroup,
|
|
11
17
|
enzyme,
|
|
@@ -16,40 +22,52 @@ export default function SingleEnzymeCutsiteInfo({
|
|
|
16
22
|
allCutsites,
|
|
17
23
|
filteredCutsites: { cutsitesByName: cutsitesByNameActive }
|
|
18
24
|
}) {
|
|
19
|
-
const onRowSelect = (
|
|
20
|
-
|
|
25
|
+
const onRowSelect = useCallback(
|
|
26
|
+
([record]) => {
|
|
27
|
+
if (!record) return;
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
dispatch({
|
|
30
|
+
type: "CARET_POSITION_UPDATE",
|
|
31
|
+
payload: record.topSnipPosition,
|
|
32
|
+
meta: {
|
|
33
|
+
editorName
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
[dispatch, editorName]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const aliases = useMemo(() => getEnzymeAliases(enzyme), [enzyme]);
|
|
41
|
+
const entities = useMemo(
|
|
42
|
+
() =>
|
|
43
|
+
cutsiteGroup
|
|
44
|
+
.sort((a, b) => a.topSnipPosition - b.topSnipPosition)
|
|
45
|
+
.map(
|
|
46
|
+
({
|
|
47
|
+
restrictionEnzyme: { forwardRegex, reverseRegex } = {},
|
|
48
|
+
forward,
|
|
49
|
+
id,
|
|
50
|
+
topSnipBeforeBottom,
|
|
51
|
+
topSnipPosition,
|
|
52
|
+
bottomSnipPosition
|
|
53
|
+
}) => {
|
|
54
|
+
return {
|
|
55
|
+
id,
|
|
56
|
+
topSnipPosition,
|
|
57
|
+
position: topSnipBeforeBottom
|
|
58
|
+
? topSnipPosition + " - " + bottomSnipPosition
|
|
59
|
+
: bottomSnipPosition + " - " + topSnipPosition,
|
|
60
|
+
strand:
|
|
61
|
+
forwardRegex === reverseRegex
|
|
62
|
+
? "Palindromic"
|
|
63
|
+
: forward
|
|
64
|
+
? "1"
|
|
65
|
+
: "-1"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
[cutsiteGroup]
|
|
70
|
+
);
|
|
53
71
|
|
|
54
72
|
return (
|
|
55
73
|
<div>
|
|
@@ -61,14 +79,12 @@ export default function SingleEnzymeCutsiteInfo({
|
|
|
61
79
|
>
|
|
62
80
|
{enzyme && (
|
|
63
81
|
<EnzymeViewer
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
forwardSnipPosition: enzyme.topSnipOffset
|
|
68
|
-
}}
|
|
82
|
+
sequence={enzyme.site}
|
|
83
|
+
reverseSnipPosition={enzyme.bottomSnipOffset}
|
|
84
|
+
forwardSnipPosition={enzyme.topSnipOffset}
|
|
69
85
|
/>
|
|
70
86
|
)}
|
|
71
|
-
<br
|
|
87
|
+
<br />
|
|
72
88
|
{entities && !!entities.length && (
|
|
73
89
|
<div>
|
|
74
90
|
<DataTable
|
|
@@ -106,7 +122,7 @@ export default function SingleEnzymeCutsiteInfo({
|
|
|
106
122
|
key={i}
|
|
107
123
|
name={n}
|
|
108
124
|
doNotShowCuts
|
|
109
|
-
|
|
125
|
+
/>
|
|
110
126
|
);
|
|
111
127
|
})}
|
|
112
128
|
</div>
|
|
@@ -117,14 +133,6 @@ export default function SingleEnzymeCutsiteInfo({
|
|
|
117
133
|
);
|
|
118
134
|
}
|
|
119
135
|
|
|
120
|
-
const schema = {
|
|
121
|
-
fields: [
|
|
122
|
-
{ path: "topSnipPosition", displayName: "Top Snip", type: "string" },
|
|
123
|
-
{ path: "position", type: "string" },
|
|
124
|
-
{ path: "strand", type: "string" }
|
|
125
|
-
]
|
|
126
|
-
};
|
|
127
|
-
|
|
128
136
|
// export default compose(
|
|
129
137
|
// withEditorProps,
|
|
130
138
|
// withRestrictionEnzymes
|