@datagrok/sequence-translator 1.10.11 → 1.10.12
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/dist/455.js +1 -1
- package/dist/455.js.map +1 -1
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +5 -5
- package/src/apps/common/view/components/colored-input/style.css +3 -1
- package/src/apps/structure/view/style.css +15 -3
- package/src/apps/structure/view/ui.ts +2 -8
- package/src/apps/translator/view/ui.ts +7 -5
- package/src/polytool/pt-enumerate-seq-dialog.ts +42 -33
- package/test-console-output-1.log +106 -212
- package/test-record-1.mp4 +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "1.10.
|
|
4
|
+
"version": "1.10.12",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Davit Rizhinashvili",
|
|
7
7
|
"email": "drizhinashvili@datagrok.ai"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@datagrok-libraries/bio": "^5.
|
|
25
|
+
"@datagrok-libraries/bio": "^5.63.6",
|
|
26
26
|
"@datagrok-libraries/chem-meta": "^1.2.8",
|
|
27
27
|
"@datagrok-libraries/tutorials": "^1.6.1",
|
|
28
28
|
"@datagrok-libraries/utils": "^4.6.5",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@datagrok-libraries/helm-web-editor": "^1.1.16",
|
|
44
44
|
"@datagrok-libraries/js-draw-lite": "^0.0.10",
|
|
45
|
-
"@datagrok/bio": "^2.
|
|
46
|
-
"@datagrok/chem": "^1.
|
|
47
|
-
"@datagrok/helm": "^2.
|
|
45
|
+
"@datagrok/bio": "^2.26.0",
|
|
46
|
+
"@datagrok/chem": "^1.17.0",
|
|
47
|
+
"@datagrok/helm": "^2.13.0",
|
|
48
48
|
"@types/jquery": "^3.5.32",
|
|
49
49
|
"@types/js-yaml": "^4.0.5",
|
|
50
50
|
"@types/lodash": "^4.14.202",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
.st-colored-text-input > textarea {
|
|
2
2
|
width: 100%;
|
|
3
|
-
|
|
3
|
+
color: transparent !important;
|
|
4
|
+
caret-color: var(--grey-6);
|
|
5
|
+
-webkit-text-fill-color: transparent !important;
|
|
4
6
|
background-color: transparent;
|
|
5
7
|
position: relative;
|
|
6
8
|
z-index: 1;
|
|
@@ -2,11 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
.st-structure-body {
|
|
4
4
|
padding-right: 20px;
|
|
5
|
+
height: 100%;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
5
8
|
}
|
|
6
9
|
|
|
7
10
|
.st-structure-mol-img {
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
flex: 1 1 0;
|
|
12
|
+
min-height: 100px;
|
|
13
|
+
min-width: 0;
|
|
14
|
+
transform: translateX(-50px);
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.st-structure-mol-img canvas {
|
|
19
|
+
max-width: 100% !important;
|
|
20
|
+
height: auto !important;
|
|
10
21
|
}
|
|
11
22
|
|
|
12
23
|
.st-structure-bool-button-block {
|
|
@@ -15,8 +26,9 @@
|
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
.st-structure-bottom {
|
|
18
|
-
flex
|
|
29
|
+
flex: 1 1 0;
|
|
19
30
|
padding-top: 20px;
|
|
31
|
+
min-height: 0;
|
|
20
32
|
}
|
|
21
33
|
|
|
22
34
|
.st-structure-clear-buttons {
|
|
@@ -52,7 +52,6 @@ class StructureAppLayout {
|
|
|
52
52
|
);
|
|
53
53
|
this.moleculeImgDiv = ui.block([]);
|
|
54
54
|
$(this.moleculeImgDiv).addClass('st-structure-mol-img');
|
|
55
|
-
|
|
56
55
|
DG.debounce<string>(this.onInput, 300).subscribe(async () => {
|
|
57
56
|
await this.updateMoleculeImg();
|
|
58
57
|
});
|
|
@@ -74,7 +73,7 @@ class StructureAppLayout {
|
|
|
74
73
|
const tableLayout = this.getTableInput(th);
|
|
75
74
|
const boolInputsAndButton = this.getBoolInputsAndButton();
|
|
76
75
|
await this.updateMoleculeImg();
|
|
77
|
-
const bottomDiv = ui.divH([
|
|
76
|
+
const bottomDiv = ui.divH([this.moleculeImgDiv, boolInputsAndButton]);
|
|
78
77
|
$(bottomDiv).addClass('st-structure-bottom');
|
|
79
78
|
|
|
80
79
|
const layout = ui.divV([tableLayout, bottomDiv]);
|
|
@@ -186,13 +185,8 @@ class StructureAppLayout {
|
|
|
186
185
|
const errStr = errorToConsole(err);
|
|
187
186
|
console.error(errStr);
|
|
188
187
|
}
|
|
189
|
-
// todo: compute relative numbers
|
|
190
|
-
const canvasWidth = 650;
|
|
191
|
-
const canvasHeight = 150;
|
|
192
188
|
const molImgObj = new MoleculeImage(molfile);
|
|
193
|
-
await molImgObj.drawMolecule(this.moleculeImgDiv,
|
|
194
|
-
// should the canvas be returned from the above function?
|
|
195
|
-
$(this.moleculeImgDiv).find('canvas').css('float', 'inherit');
|
|
189
|
+
await molImgObj.drawMolecule(this.moleculeImgDiv, 650, 150);
|
|
196
190
|
}
|
|
197
191
|
}
|
|
198
192
|
|
|
@@ -56,8 +56,6 @@ class TranslatorAppLayout {
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
$(this.formatChoiceInput.root.getElementsByTagName('select')[0]).css('width', '20%');
|
|
60
|
-
|
|
61
59
|
this.sequenceInputBase = ui.input.textArea(
|
|
62
60
|
'', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }}
|
|
63
61
|
);
|
|
@@ -235,9 +233,13 @@ class TranslatorAppLayout {
|
|
|
235
233
|
}
|
|
236
234
|
|
|
237
235
|
private saveMolfile(): void {
|
|
238
|
-
|
|
239
|
-
this.
|
|
240
|
-
|
|
236
|
+
try {
|
|
237
|
+
const result = (new SequenceToMolfileConverter(this.sequence, false,
|
|
238
|
+
this.formatChoiceInput.value!)).convert() + '\n$$$$';
|
|
239
|
+
download(this.sequence + '.sdf', encodeURIComponent(result));
|
|
240
|
+
} catch (e: any) {
|
|
241
|
+
grok.shell.warning('Unable to save SDF: ' + e.message);
|
|
242
|
+
}
|
|
241
243
|
}
|
|
242
244
|
|
|
243
245
|
private copySmiles(): void {
|
|
@@ -16,7 +16,6 @@ import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/m
|
|
|
16
16
|
import {getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
17
17
|
import '@datagrok-libraries/bio/src/types/input';
|
|
18
18
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
19
|
-
import {InputColumnBase} from '@datagrok-libraries/bio/src/types/input';
|
|
20
19
|
import {SeqValueBase} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
21
20
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
22
21
|
import {SeqTemps} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
@@ -60,7 +59,8 @@ type PolyToolEnumerateInputs = {
|
|
|
60
59
|
placeholders: PolyToolPlaceholdersInput;
|
|
61
60
|
placeholdersBreadth: PolyToolPlaceholdersBreadthInput;
|
|
62
61
|
enumeratorType: DG.ChoiceInput<PolyToolEnumeratorType>
|
|
63
|
-
|
|
62
|
+
trivialName: DG.InputBase<string>,
|
|
63
|
+
appendToTable: DG.InputBase<DG.DataFrame | null>,
|
|
64
64
|
keepOriginal: DG.InputBase<boolean>;
|
|
65
65
|
toAtomicLevel: DG.InputBase<boolean>;
|
|
66
66
|
generateHelm: DG.InputBase<boolean>;
|
|
@@ -75,7 +75,7 @@ type PolyToolEnumerateHelmSerialized = {
|
|
|
75
75
|
placeholders: string;
|
|
76
76
|
placeholdersBreadth: string;
|
|
77
77
|
enumeratorType: PolyToolEnumeratorType;
|
|
78
|
-
|
|
78
|
+
trivialName: string;
|
|
79
79
|
keepOriginal: boolean;
|
|
80
80
|
toAtomicLevel: boolean;
|
|
81
81
|
generateHelm: boolean;
|
|
@@ -170,7 +170,6 @@ async function getPolyToolEnumerateDialog(
|
|
|
170
170
|
const libHelper = await getMonomerLibHelper();
|
|
171
171
|
const monomerLib = libHelper.getMonomerLib();
|
|
172
172
|
const seqHelper = await getSeqHelper();
|
|
173
|
-
const emptyDf: DG.DataFrame = DG.DataFrame.fromColumns([]);
|
|
174
173
|
|
|
175
174
|
const helmHelper = await getHelmHelper();
|
|
176
175
|
const monomerLibFuncs = helmHelper.buildMonomersFuncsFromLib(monomerLib);
|
|
@@ -216,7 +215,6 @@ async function getPolyToolEnumerateDialog(
|
|
|
216
215
|
let srcId: { value: string, colName: string } | null = null;
|
|
217
216
|
let ruleFileList: string[];
|
|
218
217
|
let ruleInputs: RuleInputs;
|
|
219
|
-
const trivialNameSampleDiv = ui.divText('', {style: {marginLeft: '8px', marginTop: '2px'}});
|
|
220
218
|
const warningsTextDiv = ui.divText('', {style: {color: 'red'}});
|
|
221
219
|
const resultCountDiv = ui.divText('', {style: {
|
|
222
220
|
fontSize: '11px', color: 'var(--grey-4)', marginTop: '2px', marginLeft: '4px', whiteSpace: 'nowrap',
|
|
@@ -291,22 +289,17 @@ async function getPolyToolEnumerateDialog(
|
|
|
291
289
|
onValueChanged: (value: string[]) => { ruleFileList = value; }
|
|
292
290
|
})).getForm()
|
|
293
291
|
},
|
|
294
|
-
|
|
292
|
+
trivialName: ui.input.string(
|
|
295
293
|
'Trivial name', {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
onValueChanged: (): void => {
|
|
301
|
-
const valueCol = inputs.trivialNameCol.value;
|
|
302
|
-
let newSrcId: typeof srcId = null;
|
|
303
|
-
if (cell && valueCol) {
|
|
304
|
-
const originalId = valueCol.get(cell.rowIndex)!;
|
|
305
|
-
newSrcId = {value: originalId, colName: valueCol.name};
|
|
306
|
-
}
|
|
307
|
-
srcId = newSrcId;
|
|
308
|
-
trivialNameSampleDiv.textContent = srcId ? `Original ID: ${srcId.value}` : '';
|
|
294
|
+
value: '',
|
|
295
|
+
onValueChanged: (value: string): void => {
|
|
296
|
+
const trimmed = value?.trim();
|
|
297
|
+
srcId = trimmed ? {value: trimmed, colName: 'Trivial name'} : null;
|
|
309
298
|
},
|
|
299
|
+
}),
|
|
300
|
+
appendToTable: ui.input.table(
|
|
301
|
+
'Append to table', {
|
|
302
|
+
items: grok.shell.tables,
|
|
310
303
|
nullable: true,
|
|
311
304
|
}),
|
|
312
305
|
};
|
|
@@ -319,7 +312,22 @@ async function getPolyToolEnumerateDialog(
|
|
|
319
312
|
};
|
|
320
313
|
updateEnumTypeTooltip();
|
|
321
314
|
|
|
322
|
-
|
|
315
|
+
// Attach a "pick from column" icon button to the trivial name input
|
|
316
|
+
if (cell?.dataFrame) {
|
|
317
|
+
const colIcon = ui.iconFA('columns', (e: MouseEvent) => {
|
|
318
|
+
DG.Menu.popup()
|
|
319
|
+
.singleColumnSelector(cell.dataFrame, {
|
|
320
|
+
columnFilter: (col: DG.Column) => col.type === DG.COLUMN_TYPE.STRING && col !== cell.column,
|
|
321
|
+
onChange: (_grid, col: DG.Column, currentRowChanged: boolean) => {
|
|
322
|
+
if (currentRowChanged)
|
|
323
|
+
inputs.trivialName.value = col.get(cell.rowIndex) ?? '';
|
|
324
|
+
},
|
|
325
|
+
})
|
|
326
|
+
.show({x: e.clientX, y: e.clientY});
|
|
327
|
+
}, 'Pick trivial name from a column');
|
|
328
|
+
inputs.trivialName.addOptions(colIcon);
|
|
329
|
+
}
|
|
330
|
+
inputs.trivialName.root.style.maxWidth = '450px';
|
|
323
331
|
|
|
324
332
|
// Wire up monomer cell double-click to open selection dialog
|
|
325
333
|
inputs.placeholders.onMonomerCellEdit = async (position: number, currentMonomers: string[]) => {
|
|
@@ -634,14 +642,7 @@ async function getPolyToolEnumerateDialog(
|
|
|
634
642
|
}
|
|
635
643
|
};
|
|
636
644
|
|
|
637
|
-
const fillTrivialNameList = (
|
|
638
|
-
if (table) {
|
|
639
|
-
inputs.trivialNameCol.setColumnInputTable(table);
|
|
640
|
-
inputs.trivialNameCol.root.style.removeProperty('display');
|
|
641
|
-
} else {
|
|
642
|
-
inputs.trivialNameCol.setColumnInputTable(emptyDf);
|
|
643
|
-
inputs.trivialNameCol.root.style.setProperty('display', 'none');
|
|
644
|
-
}
|
|
645
|
+
const fillTrivialNameList = (_table?: DG.DataFrame) => {
|
|
645
646
|
if (resizeInputs)
|
|
646
647
|
resizeInputs();
|
|
647
648
|
};
|
|
@@ -711,7 +712,13 @@ async function getPolyToolEnumerateDialog(
|
|
|
711
712
|
rules: await ruleInputs.getActive()
|
|
712
713
|
} : false,
|
|
713
714
|
helmHelper);
|
|
714
|
-
|
|
715
|
+
const appendTarget = inputs.appendToTable.value;
|
|
716
|
+
if (appendTarget) {
|
|
717
|
+
appendTarget.append(enumeratorResDf, true);
|
|
718
|
+
appendTarget.meta.detectSemanticTypes();
|
|
719
|
+
} else {
|
|
720
|
+
grok.shell.addTableView(enumeratorResDf);
|
|
721
|
+
}
|
|
715
722
|
}
|
|
716
723
|
} catch (err: any) {
|
|
717
724
|
defaultErrorHandler(err);
|
|
@@ -735,8 +742,9 @@ async function getPolyToolEnumerateDialog(
|
|
|
735
742
|
{style: {width: '100%'}}))
|
|
736
743
|
.add(ui.divH([
|
|
737
744
|
ui.divV([
|
|
738
|
-
inputs.
|
|
739
|
-
inputs.keepOriginal.root
|
|
745
|
+
inputs.trivialName.root,
|
|
746
|
+
inputs.keepOriginal.root,
|
|
747
|
+
inputs.appendToTable.root],
|
|
740
748
|
{style: {width: '50%'}}),
|
|
741
749
|
ui.divV([
|
|
742
750
|
ui.divH([inputs.toAtomicLevel.root, inputs.generateHelm.root]),
|
|
@@ -767,7 +775,7 @@ async function getPolyToolEnumerateDialog(
|
|
|
767
775
|
placeholders: inputs.placeholders.stringValue,
|
|
768
776
|
enumeratorType: inputs.enumeratorType.value,
|
|
769
777
|
placeholdersBreadth: inputs.placeholdersBreadth.stringValue,
|
|
770
|
-
|
|
778
|
+
trivialName: inputs.trivialName.value,
|
|
771
779
|
keepOriginal: inputs.keepOriginal.value,
|
|
772
780
|
toAtomicLevel: inputs.toAtomicLevel.value,
|
|
773
781
|
generateHelm: inputs.generateHelm.value,
|
|
@@ -781,7 +789,8 @@ async function getPolyToolEnumerateDialog(
|
|
|
781
789
|
inputs.enumeratorType.value = x.enumeratorType ?? PolyToolEnumeratorTypes.Single;
|
|
782
790
|
inputs.placeholders.stringValue = x.placeholders;
|
|
783
791
|
inputs.placeholdersBreadth.stringValue = x.placeholdersBreadth;
|
|
784
|
-
|
|
792
|
+
if (x.trivialName)
|
|
793
|
+
inputs.trivialName.value = x.trivialName;
|
|
785
794
|
inputs.keepOriginal.value = x.keepOriginal ?? false;
|
|
786
795
|
inputs.toAtomicLevel.value = x.toAtomicLevel ?? true;
|
|
787
796
|
inputs.generateHelm.value = x.generateHelm ?? true;
|