ove-auto-annotate 0.0.5 → 0.0.8
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/README.md +8 -0
- package/es/index.js +74 -28
- package/lib/index.js +75 -28
- package/package.json +2 -3
- package/src/index.js +104 -43
- package/umd/ove-auto-annotate.js +34527 -797
- package/umd/ove-auto-annotate.js.map +1 -1
- package/umd/ove-auto-annotate.min.js +11 -3
- package/umd/ove-auto-annotate.min.js.map +1 -1
package/README.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# UI:
|
2
|
+

|
3
|
+
|
4
|
+

|
5
|
+
|
1
6
|
# Usage:
|
2
7
|
|
3
8
|
```js
|
@@ -43,6 +48,9 @@ window.createVectorEditor(yourDomNodeHere, {
|
|
43
48
|
|
44
49
|
# Passing a custom list of existing annotations to choose from:
|
45
50
|
|
51
|
+

|
52
|
+
|
53
|
+
|
46
54
|
```js
|
47
55
|
async function getCustomAutoAnnotateList ({ annotationType, sequenceData }) { //annotationType = feature|part|oligo
|
48
56
|
const dataToReturn = await fetch("/my/endpoint/here", { ...someParams }); //hit your endpoint here
|
package/es/index.js
CHANGED
@@ -23,6 +23,7 @@ import { formName } from "./constants";
|
|
23
23
|
import { AutoAnnotateBpMatchingDialog } from "./AutoAnnotateBpMatchingDialog";
|
24
24
|
import { parseCsvFile, validateCSVRequiredHeaders, validateCSVRow } from "./fileUtils";
|
25
25
|
import downloadjs from "downloadjs";
|
26
|
+
import { convertProteinSeqToDNAIupac } from "ve-sequence-utils";
|
26
27
|
var _window$addOnGlobals = window.addOnGlobals,
|
27
28
|
shortid = _window$addOnGlobals.shortid,
|
28
29
|
FileUploadField = _window$addOnGlobals.FileUploadField,
|
@@ -32,8 +33,8 @@ var _window$addOnGlobals = window.addOnGlobals,
|
|
32
33
|
pluralize = _window$addOnGlobals.pluralize,
|
33
34
|
reduxForm = _window$addOnGlobals.reduxForm,
|
34
35
|
SubmissionError = _window$addOnGlobals.SubmissionError,
|
35
|
-
|
36
|
-
|
36
|
+
getFeatureToColorMap = _window$addOnGlobals.getFeatureToColorMap,
|
37
|
+
getFeatureTypes = _window$addOnGlobals.getFeatureTypes,
|
37
38
|
InfoHelper = _window$addOnGlobals.InfoHelper,
|
38
39
|
showConfirmationDialog = _window$addOnGlobals.showConfirmationDialog,
|
39
40
|
wrapDialog = _window$addOnGlobals.wrapDialog,
|
@@ -79,6 +80,7 @@ export function autoAnnotatePrimers() {
|
|
79
80
|
}
|
80
81
|
export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
81
82
|
return {
|
83
|
+
canEscapeKeyClose: false,
|
82
84
|
title: "Auto Annotate " + startCase(pluralize(p.annotationType))
|
83
85
|
};
|
84
86
|
}), withEditorProps, reduxForm({
|
@@ -164,24 +166,7 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
164
166
|
onChange: setSelectedImportType,
|
165
167
|
selectedTabId: fileType
|
166
168
|
}, /*#__PURE__*/React.createElement(Tab, {
|
167
|
-
panel: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Select a CSV file
|
168
|
-
style: {
|
169
|
-
display: "flex"
|
170
|
-
}
|
171
|
-
}, "name,description,sequence,type,", /*#__PURE__*/React.createElement("span", {
|
172
|
-
style: {
|
173
|
-
display: "flex"
|
174
|
-
}
|
175
|
-
}, "isRegex \xA0", /*#__PURE__*/React.createElement(InfoHelper, {
|
176
|
-
onClick: function onClick(e) {
|
177
|
-
e.stopPropagation();
|
178
|
-
e.preventDefault();
|
179
|
-
showDialog({
|
180
|
-
ModalComponent: AutoAnnotateBpMatchingDialog
|
181
|
-
});
|
182
|
-
},
|
183
|
-
content: true ? /*#__PURE__*/React.createElement("span", null, "Any valid regexes allowed. Click for more info about regex matching") : "All valid IUPAC bases allowed as well as a couple special characters. Click for more info"
|
184
|
-
}))), /*#__PURE__*/React.createElement("br", null), annotationType !== "feature" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("i", null, "Note: the \"type\" column is optional"), /*#__PURE__*/React.createElement("br", null)), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("a", {
|
169
|
+
panel: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Select a CSV file (", /*#__PURE__*/React.createElement("a", {
|
185
170
|
onClick: function onClick() {
|
186
171
|
var rows = [_extends({
|
187
172
|
name: "Example " + startCase(annotationType) + " 1",
|
@@ -190,7 +175,17 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
190
175
|
}, annotationType === "feature" && {
|
191
176
|
type: "cds"
|
192
177
|
}, {
|
193
|
-
isRegex: false
|
178
|
+
isRegex: false,
|
179
|
+
matchType: "dna"
|
180
|
+
}), _extends({
|
181
|
+
name: "Example Protein " + startCase(annotationType),
|
182
|
+
description: "I'm a description",
|
183
|
+
sequence: "APGSGTGGGSGSAPG"
|
184
|
+
}, annotationType === "feature" && {
|
185
|
+
type: "cds"
|
186
|
+
}, {
|
187
|
+
isRegex: false,
|
188
|
+
matchType: "protein"
|
194
189
|
}), _extends({
|
195
190
|
name: "Example " + startCase(annotationType) + " 2",
|
196
191
|
description: "I'm another description",
|
@@ -198,7 +193,8 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
198
193
|
}, annotationType === "feature" && {
|
199
194
|
type: "cds"
|
200
195
|
}, {
|
201
|
-
isRegex: true
|
196
|
+
isRegex: true,
|
197
|
+
matchType: "dna"
|
202
198
|
})];
|
203
199
|
var csv = unparse(rows); // const blob = new Blob([convert(sequenceData)], { type: "text/plain" });
|
204
200
|
// const filename = `${sequenceData.name || "Untitled_Sequence"}.${fileExt}`;
|
@@ -206,7 +202,25 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
206
202
|
|
207
203
|
downloadjs(csv, "Example CSV Annotation Upload File.csv", "text/plain");
|
208
204
|
}
|
209
|
-
}, "download example")), /*#__PURE__*/React.createElement(
|
205
|
+
}, "download example"), ") with the following columns:", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("div", {
|
206
|
+
style: {
|
207
|
+
display: "flex"
|
208
|
+
}
|
209
|
+
}, "name,description,sequence,type,", /*#__PURE__*/React.createElement("span", {
|
210
|
+
style: {
|
211
|
+
display: "flex"
|
212
|
+
}
|
213
|
+
}, "isRegex \xA0", /*#__PURE__*/React.createElement(InfoHelper, {
|
214
|
+
onClick: function onClick(e) {
|
215
|
+
e.stopPropagation();
|
216
|
+
e.preventDefault();
|
217
|
+
showDialog({
|
218
|
+
ModalComponent: AutoAnnotateBpMatchingDialog
|
219
|
+
});
|
220
|
+
},
|
221
|
+
content: true ? /*#__PURE__*/React.createElement("span", null, "Any valid regexes allowed. Click for more info about regex matching") : "All valid IUPAC bases allowed as well as a couple special characters. Click for more info"
|
222
|
+
})), ",matchType"), /*#__PURE__*/React.createElement("br", null), annotationType !== "feature" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("i", null, "Note: the \"type\" column is optional"), /*#__PURE__*/React.createElement("br", null))), /*#__PURE__*/React.createElement(FileUploadField, {
|
223
|
+
validateAgainstSchema: validateAgainstSchema,
|
210
224
|
name: "csvFile",
|
211
225
|
fileLimit: 1,
|
212
226
|
isRequired: true,
|
@@ -248,7 +262,7 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
248
262
|
disabled: fileType === "implementerDefined" && !(customAnnResponse && customAnnResponse.list && customAnnResponse.list.length),
|
249
263
|
onClick: handleSubmit( /*#__PURE__*/function () {
|
250
264
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref2) {
|
251
|
-
var apeFile, csvFile, convertNonStandardTypes, annsToCheck, _seqsToAnnotateById, validateRow, _iterator, _step, _step$value, i, _step$value$, name, sequence, type, isRegex, csvHeaders, _yield$parseCsvFile, data, fields, _error, _iterator2, _step2, _step2$value, index, row, _error2, _yield$parseCsvFile2, _data, _iterator3, _step3, _step3$value, _i, _step3$value$, _name, _sequence, _type, annotationsToCheckById, seqId, _autoAnnotate, newAnns, _SubmissionError;
|
265
|
+
var apeFile, csvFile, convertNonStandardTypes, annsToCheck, _seqsToAnnotateById, validateRow, _iterator, _step, _step$value, i, _step$value$, name, sequence, matchType, type, isRegex, csvHeaders, _yield$parseCsvFile, data, fields, _error, _iterator2, _step2, _step2$value, index, row, _error2, _yield$parseCsvFile2, _data, _iterator3, _step3, _step3$value, _i, _step3$value$, _name, _sequence, _type, annotationsToCheckById, seqId, _autoAnnotate, newAnns, _SubmissionError;
|
252
266
|
|
253
267
|
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
254
268
|
while (1) {
|
@@ -274,7 +288,7 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
274
288
|
break;
|
275
289
|
}
|
276
290
|
|
277
|
-
cleanedType =
|
291
|
+
cleanedType = getFeatureTypes().find(function (t) {
|
278
292
|
return t.toLowerCase() === type.toLowerCase();
|
279
293
|
});
|
280
294
|
|
@@ -381,11 +395,12 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
381
395
|
}
|
382
396
|
|
383
397
|
_step$value = _step.value, // eslint-disable-next-line no-unused-vars
|
384
|
-
i = _step$value[0], _step$value$ = _step$value[1], name = _step$value$.name, sequence = _step$value$.sequence, type = _step$value$.type, isRegex = _step$value$.isRegex;
|
398
|
+
i = _step$value[0], _step$value$ = _step$value[1], name = _step$value$.name, sequence = _step$value$.sequence, matchType = _step$value$.matchType, type = _step$value$.type, isRegex = _step$value$.isRegex;
|
385
399
|
_context3.next = 11;
|
386
400
|
return validateRow({
|
387
401
|
name: name,
|
388
402
|
sequence: sequence,
|
403
|
+
matchType: matchType,
|
389
404
|
type: type,
|
390
405
|
isRegex: isRegex ? "TRUE" : "FALSE"
|
391
406
|
}, "Row " + (i + 1) + " (" + name + ")");
|
@@ -515,6 +530,10 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
515
530
|
case 57:
|
516
531
|
annotationsToCheckById = {};
|
517
532
|
annsToCheck.forEach(function (ann) {
|
533
|
+
if (ann.matchType === "protein") {
|
534
|
+
ann.sequence = convertProteinSeqToDNAIupac(ann.sequence);
|
535
|
+
}
|
536
|
+
|
518
537
|
var id = shortid();
|
519
538
|
annotationsToCheckById[id] = _extends({}, ann, {
|
520
539
|
sequence: ann.isRegex ? ann.sequence : convertApELikeRegexToRegex(ann.sequence),
|
@@ -536,7 +555,7 @@ export var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
536
555
|
id: shortid()
|
537
556
|
});
|
538
557
|
|
539
|
-
toRet.color = toRet.color ||
|
558
|
+
toRet.color = toRet.color || getFeatureToColorMap()[toRet.type];
|
540
559
|
return toRet;
|
541
560
|
}));
|
542
561
|
} else {
|
@@ -581,4 +600,31 @@ window._ove_addons.autoAnnotateFeatures = autoAnnotateFeatures;
|
|
581
600
|
window._ove_addons.autoAnnotateParts = autoAnnotateParts;
|
582
601
|
window._ove_addons.autoAnnotatePrimers = autoAnnotatePrimers;
|
583
602
|
var customAnnsSchema = ["name", "sequence", typeField, "isRegex"];
|
584
|
-
var customAnnsSchemaNoType = ["name", "sequence", typeField, "isRegex"];
|
603
|
+
var customAnnsSchemaNoType = ["name", "sequence", typeField, "isRegex"];
|
604
|
+
var validateAgainstSchema = {
|
605
|
+
fields: [{
|
606
|
+
path: "name",
|
607
|
+
type: "string",
|
608
|
+
isRequired: true
|
609
|
+
}, {
|
610
|
+
path: "description",
|
611
|
+
type: "string"
|
612
|
+
}, {
|
613
|
+
path: "sequence",
|
614
|
+
type: "string",
|
615
|
+
isRequired: true
|
616
|
+
}, {
|
617
|
+
path: "type",
|
618
|
+
type: "dropdown",
|
619
|
+
values: getFeatureTypes(),
|
620
|
+
defaultValue: "misc_feature"
|
621
|
+
}, {
|
622
|
+
path: "isRegex",
|
623
|
+
type: "boolean"
|
624
|
+
}, {
|
625
|
+
path: "matchType",
|
626
|
+
type: "dropdown",
|
627
|
+
defaultValue: "dna",
|
628
|
+
values: ["dna", "protein"]
|
629
|
+
}]
|
630
|
+
};
|
package/lib/index.js
CHANGED
@@ -20,6 +20,8 @@ var _fileUtils = require("./fileUtils");
|
|
20
20
|
|
21
21
|
var _downloadjs = _interopRequireDefault(require("downloadjs"));
|
22
22
|
|
23
|
+
var _veSequenceUtils = require("ve-sequence-utils");
|
24
|
+
|
23
25
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
24
26
|
|
25
27
|
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
@@ -43,8 +45,8 @@ var _window$addOnGlobals = window.addOnGlobals,
|
|
43
45
|
pluralize = _window$addOnGlobals.pluralize,
|
44
46
|
reduxForm = _window$addOnGlobals.reduxForm,
|
45
47
|
SubmissionError = _window$addOnGlobals.SubmissionError,
|
46
|
-
|
47
|
-
|
48
|
+
getFeatureToColorMap = _window$addOnGlobals.getFeatureToColorMap,
|
49
|
+
getFeatureTypes = _window$addOnGlobals.getFeatureTypes,
|
48
50
|
InfoHelper = _window$addOnGlobals.InfoHelper,
|
49
51
|
showConfirmationDialog = _window$addOnGlobals.showConfirmationDialog,
|
50
52
|
wrapDialog = _window$addOnGlobals.wrapDialog,
|
@@ -94,6 +96,7 @@ function autoAnnotatePrimers() {
|
|
94
96
|
|
95
97
|
var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
96
98
|
return {
|
99
|
+
canEscapeKeyClose: false,
|
97
100
|
title: "Auto Annotate " + startCase(pluralize(p.annotationType))
|
98
101
|
};
|
99
102
|
}), withEditorProps, reduxForm({
|
@@ -179,24 +182,7 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
179
182
|
onChange: setSelectedImportType,
|
180
183
|
selectedTabId: fileType
|
181
184
|
}, /*#__PURE__*/React.createElement(Tab, {
|
182
|
-
panel: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Select a CSV file
|
183
|
-
style: {
|
184
|
-
display: "flex"
|
185
|
-
}
|
186
|
-
}, "name,description,sequence,type,", /*#__PURE__*/React.createElement("span", {
|
187
|
-
style: {
|
188
|
-
display: "flex"
|
189
|
-
}
|
190
|
-
}, "isRegex \xA0", /*#__PURE__*/React.createElement(InfoHelper, {
|
191
|
-
onClick: function onClick(e) {
|
192
|
-
e.stopPropagation();
|
193
|
-
e.preventDefault();
|
194
|
-
showDialog({
|
195
|
-
ModalComponent: _AutoAnnotateBpMatchingDialog.AutoAnnotateBpMatchingDialog
|
196
|
-
});
|
197
|
-
},
|
198
|
-
content: true ? /*#__PURE__*/React.createElement("span", null, "Any valid regexes allowed. Click for more info about regex matching") : "All valid IUPAC bases allowed as well as a couple special characters. Click for more info"
|
199
|
-
}))), /*#__PURE__*/React.createElement("br", null), annotationType !== "feature" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("i", null, "Note: the \"type\" column is optional"), /*#__PURE__*/React.createElement("br", null)), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("a", {
|
185
|
+
panel: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Select a CSV file (", /*#__PURE__*/React.createElement("a", {
|
200
186
|
onClick: function onClick() {
|
201
187
|
var rows = [_extends({
|
202
188
|
name: "Example " + startCase(annotationType) + " 1",
|
@@ -205,7 +191,17 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
205
191
|
}, annotationType === "feature" && {
|
206
192
|
type: "cds"
|
207
193
|
}, {
|
208
|
-
isRegex: false
|
194
|
+
isRegex: false,
|
195
|
+
matchType: "dna"
|
196
|
+
}), _extends({
|
197
|
+
name: "Example Protein " + startCase(annotationType),
|
198
|
+
description: "I'm a description",
|
199
|
+
sequence: "APGSGTGGGSGSAPG"
|
200
|
+
}, annotationType === "feature" && {
|
201
|
+
type: "cds"
|
202
|
+
}, {
|
203
|
+
isRegex: false,
|
204
|
+
matchType: "protein"
|
209
205
|
}), _extends({
|
210
206
|
name: "Example " + startCase(annotationType) + " 2",
|
211
207
|
description: "I'm another description",
|
@@ -213,7 +209,8 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
213
209
|
}, annotationType === "feature" && {
|
214
210
|
type: "cds"
|
215
211
|
}, {
|
216
|
-
isRegex: true
|
212
|
+
isRegex: true,
|
213
|
+
matchType: "dna"
|
217
214
|
})];
|
218
215
|
var csv = (0, _papaparse.unparse)(rows); // const blob = new Blob([convert(sequenceData)], { type: "text/plain" });
|
219
216
|
// const filename = `${sequenceData.name || "Untitled_Sequence"}.${fileExt}`;
|
@@ -221,7 +218,25 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
221
218
|
|
222
219
|
(0, _downloadjs["default"])(csv, "Example CSV Annotation Upload File.csv", "text/plain");
|
223
220
|
}
|
224
|
-
}, "download example")), /*#__PURE__*/React.createElement(
|
221
|
+
}, "download example"), ") with the following columns:", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("div", {
|
222
|
+
style: {
|
223
|
+
display: "flex"
|
224
|
+
}
|
225
|
+
}, "name,description,sequence,type,", /*#__PURE__*/React.createElement("span", {
|
226
|
+
style: {
|
227
|
+
display: "flex"
|
228
|
+
}
|
229
|
+
}, "isRegex \xA0", /*#__PURE__*/React.createElement(InfoHelper, {
|
230
|
+
onClick: function onClick(e) {
|
231
|
+
e.stopPropagation();
|
232
|
+
e.preventDefault();
|
233
|
+
showDialog({
|
234
|
+
ModalComponent: _AutoAnnotateBpMatchingDialog.AutoAnnotateBpMatchingDialog
|
235
|
+
});
|
236
|
+
},
|
237
|
+
content: true ? /*#__PURE__*/React.createElement("span", null, "Any valid regexes allowed. Click for more info about regex matching") : "All valid IUPAC bases allowed as well as a couple special characters. Click for more info"
|
238
|
+
})), ",matchType"), /*#__PURE__*/React.createElement("br", null), annotationType !== "feature" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("i", null, "Note: the \"type\" column is optional"), /*#__PURE__*/React.createElement("br", null))), /*#__PURE__*/React.createElement(FileUploadField, {
|
239
|
+
validateAgainstSchema: validateAgainstSchema,
|
225
240
|
name: "csvFile",
|
226
241
|
fileLimit: 1,
|
227
242
|
isRequired: true,
|
@@ -263,7 +278,7 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
263
278
|
disabled: fileType === "implementerDefined" && !(customAnnResponse && customAnnResponse.list && customAnnResponse.list.length),
|
264
279
|
onClick: handleSubmit( /*#__PURE__*/function () {
|
265
280
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee3(_ref2) {
|
266
|
-
var apeFile, csvFile, convertNonStandardTypes, annsToCheck, _seqsToAnnotateById, validateRow, _iterator, _step, _step$value, i, _step$value$, name, sequence, type, isRegex, csvHeaders, _yield$parseCsvFile, data, fields, _error, _iterator2, _step2, _step2$value, index, row, _error2, _yield$parseCsvFile2, _data, _iterator3, _step3, _step3$value, _i, _step3$value$, _name, _sequence, _type, annotationsToCheckById, seqId, _autoAnnotate, newAnns, _SubmissionError;
|
281
|
+
var apeFile, csvFile, convertNonStandardTypes, annsToCheck, _seqsToAnnotateById, validateRow, _iterator, _step, _step$value, i, _step$value$, name, sequence, matchType, type, isRegex, csvHeaders, _yield$parseCsvFile, data, fields, _error, _iterator2, _step2, _step2$value, index, row, _error2, _yield$parseCsvFile2, _data, _iterator3, _step3, _step3$value, _i, _step3$value$, _name, _sequence, _type, annotationsToCheckById, seqId, _autoAnnotate, newAnns, _SubmissionError;
|
267
282
|
|
268
283
|
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
269
284
|
while (1) {
|
@@ -289,7 +304,7 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
289
304
|
break;
|
290
305
|
}
|
291
306
|
|
292
|
-
cleanedType =
|
307
|
+
cleanedType = getFeatureTypes().find(function (t) {
|
293
308
|
return t.toLowerCase() === type.toLowerCase();
|
294
309
|
});
|
295
310
|
|
@@ -396,11 +411,12 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
396
411
|
}
|
397
412
|
|
398
413
|
_step$value = _step.value, // eslint-disable-next-line no-unused-vars
|
399
|
-
i = _step$value[0], _step$value$ = _step$value[1], name = _step$value$.name, sequence = _step$value$.sequence, type = _step$value$.type, isRegex = _step$value$.isRegex;
|
414
|
+
i = _step$value[0], _step$value$ = _step$value[1], name = _step$value$.name, sequence = _step$value$.sequence, matchType = _step$value$.matchType, type = _step$value$.type, isRegex = _step$value$.isRegex;
|
400
415
|
_context3.next = 11;
|
401
416
|
return validateRow({
|
402
417
|
name: name,
|
403
418
|
sequence: sequence,
|
419
|
+
matchType: matchType,
|
404
420
|
type: type,
|
405
421
|
isRegex: isRegex ? "TRUE" : "FALSE"
|
406
422
|
}, "Row " + (i + 1) + " (" + name + ")");
|
@@ -530,6 +546,10 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
530
546
|
case 57:
|
531
547
|
annotationsToCheckById = {};
|
532
548
|
annsToCheck.forEach(function (ann) {
|
549
|
+
if (ann.matchType === "protein") {
|
550
|
+
ann.sequence = (0, _veSequenceUtils.convertProteinSeqToDNAIupac)(ann.sequence);
|
551
|
+
}
|
552
|
+
|
533
553
|
var id = shortid();
|
534
554
|
annotationsToCheckById[id] = _extends({}, ann, {
|
535
555
|
sequence: ann.isRegex ? ann.sequence : convertApELikeRegexToRegex(ann.sequence),
|
@@ -551,7 +571,7 @@ var AutoAnnotateModal = compose(wrapDialog(function (p) {
|
|
551
571
|
id: shortid()
|
552
572
|
});
|
553
573
|
|
554
|
-
toRet.color = toRet.color ||
|
574
|
+
toRet.color = toRet.color || getFeatureToColorMap()[toRet.type];
|
555
575
|
return toRet;
|
556
576
|
}));
|
557
577
|
} else {
|
@@ -597,4 +617,31 @@ window._ove_addons.autoAnnotateFeatures = autoAnnotateFeatures;
|
|
597
617
|
window._ove_addons.autoAnnotateParts = autoAnnotateParts;
|
598
618
|
window._ove_addons.autoAnnotatePrimers = autoAnnotatePrimers;
|
599
619
|
var customAnnsSchema = ["name", "sequence", typeField, "isRegex"];
|
600
|
-
var customAnnsSchemaNoType = ["name", "sequence", typeField, "isRegex"];
|
620
|
+
var customAnnsSchemaNoType = ["name", "sequence", typeField, "isRegex"];
|
621
|
+
var validateAgainstSchema = {
|
622
|
+
fields: [{
|
623
|
+
path: "name",
|
624
|
+
type: "string",
|
625
|
+
isRequired: true
|
626
|
+
}, {
|
627
|
+
path: "description",
|
628
|
+
type: "string"
|
629
|
+
}, {
|
630
|
+
path: "sequence",
|
631
|
+
type: "string",
|
632
|
+
isRequired: true
|
633
|
+
}, {
|
634
|
+
path: "type",
|
635
|
+
type: "dropdown",
|
636
|
+
values: getFeatureTypes(),
|
637
|
+
defaultValue: "misc_feature"
|
638
|
+
}, {
|
639
|
+
path: "isRegex",
|
640
|
+
type: "boolean"
|
641
|
+
}, {
|
642
|
+
path: "matchType",
|
643
|
+
type: "dropdown",
|
644
|
+
defaultValue: "dna",
|
645
|
+
values: ["dna", "protein"]
|
646
|
+
}]
|
647
|
+
};
|
package/package.json
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "ove-auto-annotate",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.8",
|
4
4
|
"scripts": {
|
5
5
|
"build": "nwb build-react-component --copy-files --no-demo",
|
6
|
-
"
|
6
|
+
"prepublishOnly": "npm run build"
|
7
7
|
},
|
8
8
|
"dependencies": {
|
9
|
-
"downloadjs": "^1.4.7",
|
10
9
|
"papaparse": "^5.3.1"
|
11
10
|
},
|
12
11
|
"devDependencies": {
|
package/src/index.js
CHANGED
@@ -11,6 +11,7 @@ import {
|
|
11
11
|
validateCSVRow
|
12
12
|
} from "./fileUtils";
|
13
13
|
import downloadjs from "downloadjs";
|
14
|
+
import { convertProteinSeqToDNAIupac } from "ve-sequence-utils";
|
14
15
|
|
15
16
|
const {
|
16
17
|
shortid,
|
@@ -21,8 +22,8 @@ const {
|
|
21
22
|
pluralize,
|
22
23
|
reduxForm,
|
23
24
|
SubmissionError,
|
24
|
-
|
25
|
-
|
25
|
+
getFeatureToColorMap,
|
26
|
+
getFeatureTypes,
|
26
27
|
InfoHelper,
|
27
28
|
showConfirmationDialog,
|
28
29
|
wrapDialog,
|
@@ -68,6 +69,7 @@ export function autoAnnotatePrimers() {
|
|
68
69
|
|
69
70
|
export const AutoAnnotateModal = compose(
|
70
71
|
wrapDialog((p) => ({
|
72
|
+
canEscapeKeyClose: false,
|
71
73
|
title: `Auto Annotate ${startCase(pluralize(p.annotationType))}`
|
72
74
|
})),
|
73
75
|
withEditorProps,
|
@@ -120,41 +122,7 @@ export const AutoAnnotateModal = compose(
|
|
120
122
|
panel={
|
121
123
|
<div>
|
122
124
|
<div>
|
123
|
-
Select a CSV file
|
124
|
-
<br></br>
|
125
|
-
<div style={{ display: "flex" }}>
|
126
|
-
name,description,sequence,type,
|
127
|
-
<span style={{ display: "flex" }}>
|
128
|
-
isRegex
|
129
|
-
<InfoHelper
|
130
|
-
onClick={(e) => {
|
131
|
-
e.stopPropagation();
|
132
|
-
e.preventDefault();
|
133
|
-
showDialog({
|
134
|
-
ModalComponent: AutoAnnotateBpMatchingDialog
|
135
|
-
});
|
136
|
-
}}
|
137
|
-
content={
|
138
|
-
true ? (
|
139
|
-
<span>
|
140
|
-
Any valid regexes allowed. Click for more info about
|
141
|
-
regex matching
|
142
|
-
</span>
|
143
|
-
) : (
|
144
|
-
`All valid IUPAC bases allowed as well as a couple special characters. Click for more info`
|
145
|
-
)
|
146
|
-
}
|
147
|
-
></InfoHelper>
|
148
|
-
</span>
|
149
|
-
</div>
|
150
|
-
<br></br>
|
151
|
-
{annotationType !== "feature" && (
|
152
|
-
<React.Fragment>
|
153
|
-
<i>Note: the "type" column is optional</i>
|
154
|
-
<br></br>
|
155
|
-
</React.Fragment>
|
156
|
-
)}
|
157
|
-
<br></br>
|
125
|
+
Select a CSV file (
|
158
126
|
<a
|
159
127
|
onClick={() => {
|
160
128
|
const rows = [
|
@@ -165,7 +133,18 @@ export const AutoAnnotateModal = compose(
|
|
165
133
|
...(annotationType === "feature" && {
|
166
134
|
type: `cds`
|
167
135
|
}),
|
168
|
-
isRegex: false
|
136
|
+
isRegex: false,
|
137
|
+
matchType: "dna"
|
138
|
+
},
|
139
|
+
{
|
140
|
+
name: `Example Protein ${startCase(annotationType)}`,
|
141
|
+
description: "I'm a description",
|
142
|
+
sequence: `APGSGTGGGSGSAPG`,
|
143
|
+
...(annotationType === "feature" && {
|
144
|
+
type: `cds`
|
145
|
+
}),
|
146
|
+
isRegex: false,
|
147
|
+
matchType: "protein"
|
169
148
|
},
|
170
149
|
{
|
171
150
|
name: `Example ${startCase(annotationType)} 2`,
|
@@ -174,7 +153,8 @@ export const AutoAnnotateModal = compose(
|
|
174
153
|
...(annotationType === "feature" && {
|
175
154
|
type: `cds`
|
176
155
|
}),
|
177
|
-
isRegex: true
|
156
|
+
isRegex: true,
|
157
|
+
matchType: "dna"
|
178
158
|
}
|
179
159
|
];
|
180
160
|
const csv = unparse(rows);
|
@@ -190,8 +170,44 @@ export const AutoAnnotateModal = compose(
|
|
190
170
|
>
|
191
171
|
download example
|
192
172
|
</a>
|
173
|
+
) with the following columns:<br></br>
|
174
|
+
<br></br>
|
175
|
+
<div style={{ display: "flex" }}>
|
176
|
+
name,description,sequence,type,
|
177
|
+
<span style={{ display: "flex" }}>
|
178
|
+
isRegex
|
179
|
+
<InfoHelper
|
180
|
+
onClick={(e) => {
|
181
|
+
e.stopPropagation();
|
182
|
+
e.preventDefault();
|
183
|
+
showDialog({
|
184
|
+
ModalComponent: AutoAnnotateBpMatchingDialog
|
185
|
+
});
|
186
|
+
}}
|
187
|
+
content={
|
188
|
+
true ? (
|
189
|
+
<span>
|
190
|
+
Any valid regexes allowed. Click for more info about
|
191
|
+
regex matching
|
192
|
+
</span>
|
193
|
+
) : (
|
194
|
+
`All valid IUPAC bases allowed as well as a couple special characters. Click for more info`
|
195
|
+
)
|
196
|
+
}
|
197
|
+
></InfoHelper>
|
198
|
+
</span>
|
199
|
+
,matchType
|
200
|
+
</div>
|
201
|
+
<br></br>
|
202
|
+
{annotationType !== "feature" && (
|
203
|
+
<React.Fragment>
|
204
|
+
<i>Note: the "type" column is optional</i>
|
205
|
+
<br></br>
|
206
|
+
</React.Fragment>
|
207
|
+
)}
|
193
208
|
</div>
|
194
209
|
<FileUploadField
|
210
|
+
validateAgainstSchema={validateAgainstSchema}
|
195
211
|
name="csvFile"
|
196
212
|
fileLimit={1}
|
197
213
|
isRequired
|
@@ -285,7 +301,7 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
285
301
|
let regexConvertedSeq;
|
286
302
|
|
287
303
|
if (annotationType === "feature") {
|
288
|
-
const cleanedType =
|
304
|
+
const cleanedType = getFeatureTypes().find(
|
289
305
|
(t) => t.toLowerCase() === type.toLowerCase()
|
290
306
|
);
|
291
307
|
if (!cleanedType) {
|
@@ -329,10 +345,16 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
329
345
|
// eslint-disable-next-line no-unused-vars
|
330
346
|
i,
|
331
347
|
// eslint-disable-next-line no-unused-vars
|
332
|
-
{ name, sequence, type, isRegex }
|
348
|
+
{ name, sequence, matchType, type, isRegex }
|
333
349
|
] of customAnnResponse.list.entries()) {
|
334
350
|
await validateRow(
|
335
|
-
{
|
351
|
+
{
|
352
|
+
name,
|
353
|
+
sequence,
|
354
|
+
matchType,
|
355
|
+
type,
|
356
|
+
isRegex: isRegex ? "TRUE" : "FALSE"
|
357
|
+
},
|
336
358
|
`Row ${i + 1} (${name})`
|
337
359
|
);
|
338
360
|
}
|
@@ -386,6 +408,9 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
386
408
|
}
|
387
409
|
const annotationsToCheckById = {};
|
388
410
|
annsToCheck.forEach((ann) => {
|
411
|
+
if (ann.matchType === "protein") {
|
412
|
+
ann.sequence = convertProteinSeqToDNAIupac(ann.sequence);
|
413
|
+
}
|
389
414
|
const id = shortid();
|
390
415
|
annotationsToCheckById[id] = {
|
391
416
|
...ann,
|
@@ -413,7 +438,8 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
413
438
|
forward: a.strand !== -1,
|
414
439
|
id: shortid()
|
415
440
|
};
|
416
|
-
toRet.color =
|
441
|
+
toRet.color =
|
442
|
+
toRet.color || getFeatureToColorMap()[toRet.type];
|
417
443
|
return toRet;
|
418
444
|
})
|
419
445
|
);
|
@@ -446,3 +472,38 @@ window._ove_addons.autoAnnotatePrimers = autoAnnotatePrimers;
|
|
446
472
|
|
447
473
|
const customAnnsSchema = ["name", "sequence", typeField, "isRegex"];
|
448
474
|
const customAnnsSchemaNoType = ["name", "sequence", typeField, "isRegex"];
|
475
|
+
|
476
|
+
const validateAgainstSchema = {
|
477
|
+
fields: [
|
478
|
+
{
|
479
|
+
path: "name",
|
480
|
+
type: "string",
|
481
|
+
isRequired: true
|
482
|
+
},
|
483
|
+
{
|
484
|
+
path: "description",
|
485
|
+
type: "string"
|
486
|
+
},
|
487
|
+
{
|
488
|
+
path: "sequence",
|
489
|
+
type: "string",
|
490
|
+
isRequired: true
|
491
|
+
},
|
492
|
+
{
|
493
|
+
path: "type",
|
494
|
+
type: "dropdown",
|
495
|
+
values: getFeatureTypes(),
|
496
|
+
defaultValue: "misc_feature"
|
497
|
+
},
|
498
|
+
{
|
499
|
+
path: "isRegex",
|
500
|
+
type: "boolean"
|
501
|
+
},
|
502
|
+
{
|
503
|
+
path: "matchType",
|
504
|
+
type: "dropdown",
|
505
|
+
defaultValue: "dna",
|
506
|
+
values: ["dna", "protein"]
|
507
|
+
}
|
508
|
+
]
|
509
|
+
};
|