ove-auto-annotate 0.0.4 → 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 +80 -33
- package/lib/index.js +81 -33
- package/package.json +2 -3
- package/src/index.js +109 -51
- package/umd/ove-auto-annotate.js +34530 -799
- 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/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,
|
@@ -99,7 +101,8 @@ export const AutoAnnotateModal = compose(
|
|
99
101
|
}
|
100
102
|
}
|
101
103
|
})();
|
102
|
-
|
104
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
105
|
+
}, []);
|
103
106
|
if (newAnnotations) {
|
104
107
|
return (
|
105
108
|
<CreateAnnotationsPage
|
@@ -119,41 +122,7 @@ export const AutoAnnotateModal = compose(
|
|
119
122
|
panel={
|
120
123
|
<div>
|
121
124
|
<div>
|
122
|
-
Select a CSV file
|
123
|
-
<br></br>
|
124
|
-
<div style={{ display: "flex" }}>
|
125
|
-
name,description,sequence,type,
|
126
|
-
<span style={{ display: "flex" }}>
|
127
|
-
isRegex
|
128
|
-
<InfoHelper
|
129
|
-
onClick={(e) => {
|
130
|
-
e.stopPropagation();
|
131
|
-
e.preventDefault();
|
132
|
-
showDialog({
|
133
|
-
ModalComponent: AutoAnnotateBpMatchingDialog
|
134
|
-
});
|
135
|
-
}}
|
136
|
-
content={
|
137
|
-
true ? (
|
138
|
-
<span>
|
139
|
-
Any valid regexes allowed. Click for more info about
|
140
|
-
regex matching
|
141
|
-
</span>
|
142
|
-
) : (
|
143
|
-
`All valid IUPAC bases allowed as well as a couple special characters. Click for more info`
|
144
|
-
)
|
145
|
-
}
|
146
|
-
></InfoHelper>
|
147
|
-
</span>
|
148
|
-
</div>
|
149
|
-
<br></br>
|
150
|
-
{annotationType !== "feature" && (
|
151
|
-
<React.Fragment>
|
152
|
-
<i>Note: the "type" column is optional</i>
|
153
|
-
<br></br>
|
154
|
-
</React.Fragment>
|
155
|
-
)}
|
156
|
-
<br></br>
|
125
|
+
Select a CSV file (
|
157
126
|
<a
|
158
127
|
onClick={() => {
|
159
128
|
const rows = [
|
@@ -164,7 +133,18 @@ export const AutoAnnotateModal = compose(
|
|
164
133
|
...(annotationType === "feature" && {
|
165
134
|
type: `cds`
|
166
135
|
}),
|
167
|
-
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"
|
168
148
|
},
|
169
149
|
{
|
170
150
|
name: `Example ${startCase(annotationType)} 2`,
|
@@ -173,7 +153,8 @@ export const AutoAnnotateModal = compose(
|
|
173
153
|
...(annotationType === "feature" && {
|
174
154
|
type: `cds`
|
175
155
|
}),
|
176
|
-
isRegex: true
|
156
|
+
isRegex: true,
|
157
|
+
matchType: "dna"
|
177
158
|
}
|
178
159
|
];
|
179
160
|
const csv = unparse(rows);
|
@@ -189,8 +170,44 @@ export const AutoAnnotateModal = compose(
|
|
189
170
|
>
|
190
171
|
download example
|
191
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
|
+
)}
|
192
208
|
</div>
|
193
209
|
<FileUploadField
|
210
|
+
validateAgainstSchema={validateAgainstSchema}
|
194
211
|
name="csvFile"
|
195
212
|
fileLimit={1}
|
196
213
|
isRequired
|
@@ -239,16 +256,12 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
239
256
|
(loadingCustomAnnList ? (
|
240
257
|
<Tab disabled title="Loading..."></Tab>
|
241
258
|
) : (
|
242
|
-
customAnnResponse &&
|
259
|
+
customAnnResponse &&
|
260
|
+
customAnnResponse.list && (
|
243
261
|
<Tab
|
244
262
|
id="implementerDefined"
|
245
|
-
title={
|
246
|
-
(customAnnResponse && customAnnResponse.title) ||
|
247
|
-
"Custom List"
|
248
|
-
}
|
263
|
+
title={customAnnResponse.title || "Custom List"}
|
249
264
|
panel={
|
250
|
-
customAnnResponse &&
|
251
|
-
customAnnResponse.list &&
|
252
265
|
customAnnResponse.list.length ? (
|
253
266
|
<div>
|
254
267
|
<DataTable
|
@@ -288,7 +301,7 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
288
301
|
let regexConvertedSeq;
|
289
302
|
|
290
303
|
if (annotationType === "feature") {
|
291
|
-
const cleanedType =
|
304
|
+
const cleanedType = getFeatureTypes().find(
|
292
305
|
(t) => t.toLowerCase() === type.toLowerCase()
|
293
306
|
);
|
294
307
|
if (!cleanedType) {
|
@@ -332,10 +345,16 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
332
345
|
// eslint-disable-next-line no-unused-vars
|
333
346
|
i,
|
334
347
|
// eslint-disable-next-line no-unused-vars
|
335
|
-
{ name, sequence, type, isRegex }
|
348
|
+
{ name, sequence, matchType, type, isRegex }
|
336
349
|
] of customAnnResponse.list.entries()) {
|
337
350
|
await validateRow(
|
338
|
-
{
|
351
|
+
{
|
352
|
+
name,
|
353
|
+
sequence,
|
354
|
+
matchType,
|
355
|
+
type,
|
356
|
+
isRegex: isRegex ? "TRUE" : "FALSE"
|
357
|
+
},
|
339
358
|
`Row ${i + 1} (${name})`
|
340
359
|
);
|
341
360
|
}
|
@@ -389,6 +408,9 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
389
408
|
}
|
390
409
|
const annotationsToCheckById = {};
|
391
410
|
annsToCheck.forEach((ann) => {
|
411
|
+
if (ann.matchType === "protein") {
|
412
|
+
ann.sequence = convertProteinSeqToDNAIupac(ann.sequence);
|
413
|
+
}
|
392
414
|
const id = shortid();
|
393
415
|
annotationsToCheckById[id] = {
|
394
416
|
...ann,
|
@@ -416,7 +438,8 @@ FRT GAAGTTCCTATTCTCTAGAAAGTATAGGAACTTC misc_recomb orchid pink 0 0`,
|
|
416
438
|
forward: a.strand !== -1,
|
417
439
|
id: shortid()
|
418
440
|
};
|
419
|
-
toRet.color =
|
441
|
+
toRet.color =
|
442
|
+
toRet.color || getFeatureToColorMap()[toRet.type];
|
420
443
|
return toRet;
|
421
444
|
})
|
422
445
|
);
|
@@ -449,3 +472,38 @@ window._ove_addons.autoAnnotatePrimers = autoAnnotatePrimers;
|
|
449
472
|
|
450
473
|
const customAnnsSchema = ["name", "sequence", typeField, "isRegex"];
|
451
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
|
+
};
|