@datagrok/sequence-translator 1.3.5 → 1.3.9
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/CHANGELOG.md +27 -0
- package/detectors.js +32 -0
- 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 +10 -6
- package/src/apps/common/view/components/colored-input/style.css +3 -2
- package/src/apps/pattern/model/data-manager.ts +4 -1
- package/src/apps/pattern/model/translator.ts +45 -8
- package/src/apps/pattern/view/components/bulk-convert/column-input.ts +4 -10
- package/src/apps/pattern/view/components/bulk-convert/table-input.ts +5 -8
- package/src/apps/pattern/view/components/edit-block-controls.ts +6 -15
- package/src/apps/pattern/view/components/load-block-controls.ts +7 -9
- package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +4 -5
- package/src/apps/pattern/view/components/strand-editor/header-controls.ts +2 -2
- package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +2 -2
- package/src/apps/pattern/view/components/terminal-modification-editor.ts +1 -1
- package/src/apps/pattern/view/components/translation-examples-block.ts +1 -1
- package/src/apps/structure/view/ui.ts +5 -5
- package/src/apps/translator/view/ui.ts +15 -27
- package/src/package.ts +52 -11
- package/src/plugins/mermade.ts +1 -1
- package/src/polytool/pt-conversion.ts +2 -2
- package/src/polytool/pt-dialog.ts +99 -18
- package/src/polytool/pt-enumeration-chem.ts +105 -0
- package/src/polytool/pt-enumeration-helm.ts +22 -0
- package/src/polytool/pt-ui.ts +25 -0
- package/src/polytool/utils.ts +34 -3
- package/src/utils/context-menu.ts +57 -0
- package/src/utils/err-info.ts +13 -0
- package/webpack.config.js +2 -4
- package/src/polytool/pt-enumeration.ts +0 -141
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.9",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexey Choposky",
|
|
7
7
|
"email": "achopovsky@datagrok.ai"
|
|
@@ -22,23 +22,26 @@
|
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@datagrok-libraries/bio": "
|
|
25
|
+
"@datagrok-libraries/bio": "5.42.5",
|
|
26
26
|
"@datagrok-libraries/chem-meta": "^1.2.5",
|
|
27
27
|
"@datagrok-libraries/tutorials": "^1.3.12",
|
|
28
|
-
"@datagrok-libraries/utils": "^4.2.
|
|
28
|
+
"@datagrok-libraries/utils": "^4.2.13",
|
|
29
29
|
"@types/react": "^18.0.15",
|
|
30
30
|
"cash-dom": "^8.1.0",
|
|
31
|
-
"datagrok-api": "^1.
|
|
31
|
+
"datagrok-api": "^1.20.0",
|
|
32
32
|
"lodash": "^4.17.21",
|
|
33
33
|
"object-hash": "^3.0.0",
|
|
34
34
|
"openchemlib": "6.0.1",
|
|
35
35
|
"save-svg-as-png": "^1.4.17",
|
|
36
36
|
"ts-loader": "^9.3.1",
|
|
37
37
|
"typeahead-standalone": "4.14.1",
|
|
38
|
-
"typescript": "^5.4.2"
|
|
38
|
+
"typescript": "^5.4.2",
|
|
39
|
+
"wu": "latest"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@datagrok/
|
|
42
|
+
"@datagrok-libraries/helm-web-editor": "^1.1.6",
|
|
43
|
+
"@datagrok-libraries/js-draw-lite": "^0.0.4",
|
|
44
|
+
"@datagrok/bio": "^2.13.3",
|
|
42
45
|
"@datagrok/chem": "1.9.2",
|
|
43
46
|
"@types/jquery": "^3.5.14",
|
|
44
47
|
"@types/js-yaml": "^4.0.5",
|
|
@@ -46,6 +49,7 @@
|
|
|
46
49
|
"@types/node-fetch": "^2.6.2",
|
|
47
50
|
"@types/object-hash": "^3.0.6",
|
|
48
51
|
"@types/react": "^18.0.15",
|
|
52
|
+
"@types/wu": "latest",
|
|
49
53
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
|
50
54
|
"@typescript-eslint/parser": "^7.2.0",
|
|
51
55
|
"css-loader": "^6.7.3",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
max-width: 100%;
|
|
20
20
|
padding: 2px;
|
|
21
21
|
line-height: normal;
|
|
22
|
-
font-family: 'Roboto
|
|
23
|
-
font-size:
|
|
22
|
+
font-family: 'Roboto', 'Roboto Local', sans-serif;
|
|
23
|
+
font-size: 13px;
|
|
24
|
+
padding-top: 6px !important;
|
|
24
25
|
color: transparent;
|
|
25
26
|
white-space: pre-wrap;
|
|
26
27
|
word-wrap: break-word;
|
|
@@ -274,7 +274,10 @@ export class DataManager {
|
|
|
274
274
|
this.currentUserPatternNameToHash.set(patternName, patternHash);
|
|
275
275
|
} else {
|
|
276
276
|
if (!userIdsToUserNames.has(authorID)) {
|
|
277
|
-
|
|
277
|
+
let userFriendlyName = '<UNKNOWN_USER>';
|
|
278
|
+
try {
|
|
279
|
+
userFriendlyName = (await grok.dapi.users.find(authorID)).friendlyName;
|
|
280
|
+
} catch (e) {}
|
|
278
281
|
userIdsToUserNames.set(authorID, userFriendlyName);
|
|
279
282
|
}
|
|
280
283
|
const fullPatternName = patternName + ` (created by ${userIdsToUserNames.get(authorID)})`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
3
|
import {STRAND, STRANDS, TERMINI, TERMINUS} from './const';
|
|
3
4
|
import {EventBus} from './event-bus';
|
|
4
|
-
import {ITranslationHelper} from '../../../types';
|
|
5
5
|
import {_package} from '../../../package';
|
|
6
6
|
import {JsonData} from '../../common/model/data-loader/json-loader';
|
|
7
7
|
|
|
@@ -11,13 +11,18 @@ export function bulkTranslate(eventBus: EventBus): void {
|
|
|
11
11
|
grok.shell.warning('Please select a table');
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
const
|
|
14
|
+
const strandInputData = STRANDS.filter(
|
|
15
15
|
(strand) => !(strand === STRAND.ANTISENSE && !eventBus.isAntisenseStrandActive())
|
|
16
|
-
).map((strand) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
).map((strand) => {
|
|
17
|
+
return {
|
|
18
|
+
strand,
|
|
19
|
+
column: eventBus.getSelectedStrandColumn(strand)
|
|
20
|
+
};
|
|
21
|
+
})
|
|
22
|
+
.filter((el) => el.column);
|
|
23
|
+
|
|
24
|
+
if (strandInputData.length === 0) {
|
|
25
|
+
grok.shell.warning('Select a sense strand column');
|
|
21
26
|
return;
|
|
22
27
|
}
|
|
23
28
|
|
|
@@ -26,9 +31,41 @@ export function bulkTranslate(eventBus: EventBus): void {
|
|
|
26
31
|
|
|
27
32
|
const idColumn = df.getCol(idColumnName);
|
|
28
33
|
|
|
29
|
-
const
|
|
34
|
+
const strandColData = strandInputData.map((el) => {
|
|
35
|
+
return {strand: el.strand, column: df.getCol(el.column!)};
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (!areStrandColsValid(strandColData, eventBus)) {
|
|
39
|
+
grok.shell.warning(`Some strands in the table input do not match pattern length`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
strandColData.forEach((strandColData) => {
|
|
44
|
+
const inputCol = strandColData.column;
|
|
45
|
+
const strand = strandColData.strand;
|
|
46
|
+
const modifications = eventBus.getNucleotideSequences()[strand];
|
|
47
|
+
const terminals = eventBus.getTerminalModifications()[strand];
|
|
48
|
+
const ptoFlags = eventBus.getPhosphorothioateLinkageFlags()[strand];
|
|
49
|
+
|
|
50
|
+
const outputColName = `${eventBus.getPatternName()}(${inputCol.name})`;
|
|
51
|
+
df.columns.addNewString(outputColName).init((i) => {
|
|
52
|
+
const input = inputCol.get(i);
|
|
53
|
+
return applyPatternToRawSequence(
|
|
54
|
+
input, modifications, ptoFlags, terminals
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
30
58
|
}
|
|
31
59
|
|
|
60
|
+
function areStrandColsValid(strandColumns: {strand: STRAND, column: DG.Column<string>}[], eventBus: EventBus) {
|
|
61
|
+
const nucleotides = eventBus.getNucleotideSequences();
|
|
62
|
+
return strandColumns.every((el) => {
|
|
63
|
+
const patternLength = nucleotides[el.strand].length;
|
|
64
|
+
return el.column.toList().every((input) => input.length === patternLength);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
32
69
|
export function applyPatternToRawSequence(
|
|
33
70
|
rawNucleotideSequence: string,
|
|
34
71
|
modifications: string[],
|
|
@@ -53,11 +53,8 @@ export class ColumnInputManager {
|
|
|
53
53
|
this.selectedTable.columns.names().sort((a, b) => a.localeCompare(b)) :
|
|
54
54
|
[];
|
|
55
55
|
const strandColumnInput = Object.fromEntries(STRANDS.map((strand) => {
|
|
56
|
-
const input = ui.
|
|
57
|
-
|
|
58
|
-
columns[0],
|
|
59
|
-
columns,
|
|
60
|
-
(colName: string) => this.eventBus.selectStrandColumn(strand, colName)
|
|
56
|
+
const input = ui.input.choice(`${STRAND_LABEL[strand]} column`, {value: columns[0], items: columns,
|
|
57
|
+
onValueChanged: (input) => this.eventBus.selectStrandColumn(strand, input.value)}
|
|
61
58
|
);
|
|
62
59
|
this.eventBus.selectStrandColumn(strand, columns[0]);
|
|
63
60
|
return [strand, input.root];
|
|
@@ -67,11 +64,8 @@ export class ColumnInputManager {
|
|
|
67
64
|
|
|
68
65
|
private createIdColumnInput(): HTMLElement {
|
|
69
66
|
const columns = this.selectedTable ? this.selectedTable.columns.names() : [];
|
|
70
|
-
const idColumnInput = ui.
|
|
71
|
-
|
|
72
|
-
columns[0],
|
|
73
|
-
columns,
|
|
74
|
-
(colName: string) => this.eventBus.selectIdColumn(colName)
|
|
67
|
+
const idColumnInput = ui.input.choice('ID column', {value: columns[0], items: columns,
|
|
68
|
+
onValueChanged: (input) => this.eventBus.selectIdColumn(input.value)}
|
|
75
69
|
);
|
|
76
70
|
this.eventBus.selectIdColumn(columns[0]);
|
|
77
71
|
return idColumnInput.root;
|
|
@@ -63,16 +63,13 @@ export class TableInputManager {
|
|
|
63
63
|
private createTableInput(): DG.InputBase<DG.DataFrame | null> {
|
|
64
64
|
const currentlySelectedTable = this.eventBus.getTableSelection();
|
|
65
65
|
|
|
66
|
-
const tableInput = ui.
|
|
67
|
-
|
|
68
|
-
currentlySelectedTable,
|
|
69
|
-
this.availableTables,
|
|
70
|
-
(table: DG.DataFrame) => {
|
|
66
|
+
const tableInput = ui.input.table('Tables', {value: currentlySelectedTable!, items: this.availableTables,
|
|
67
|
+
onValueChanged: (input) => {
|
|
71
68
|
// WARNING: non-null check necessary to prevent resetting columns to
|
|
72
69
|
// null upon handling onTableAdded
|
|
73
|
-
if (
|
|
74
|
-
this.eventBus.selectTable(
|
|
75
|
-
});
|
|
70
|
+
if (input.value !== null)
|
|
71
|
+
this.eventBus.selectTable(input.value);
|
|
72
|
+
}});
|
|
76
73
|
return tableInput;
|
|
77
74
|
}
|
|
78
75
|
|
|
@@ -74,9 +74,9 @@ export class PatternEditControlsManager {
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
private createAntisenseStrandToggle(): HTMLElement {
|
|
77
|
-
const toggleAntisenseStrand = ui.
|
|
77
|
+
const toggleAntisenseStrand = ui.input.toggle(
|
|
78
78
|
`${STRAND_LABEL[STRAND.ANTISENSE]} strand`,
|
|
79
|
-
this.eventBus.isAntisenseStrandActive()
|
|
79
|
+
{value: this.eventBus.isAntisenseStrandActive()}
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
toggleAntisenseStrand.onInput(
|
|
@@ -96,10 +96,7 @@ export class PatternEditControlsManager {
|
|
|
96
96
|
const createStrandLengthInput = (strand: StrandType) => {
|
|
97
97
|
const sequenceLength = this.eventBus.getNucleotideSequences()[strand].length;
|
|
98
98
|
|
|
99
|
-
const input = ui.
|
|
100
|
-
`${STRAND_LABEL[strand]} length`,
|
|
101
|
-
sequenceLength
|
|
102
|
-
);
|
|
99
|
+
const input = ui.input.int(`${STRAND_LABEL[strand]} length`, {value: sequenceLength});
|
|
103
100
|
input.onInput(() => updateStrandLengthInputs(strand, input));
|
|
104
101
|
|
|
105
102
|
this.eventBus.nucleotideSequencesChanged$.subscribe(() => {
|
|
@@ -142,7 +139,7 @@ export class PatternEditControlsManager {
|
|
|
142
139
|
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
143
140
|
const defaultNucleotideBase = this.dataManager.fetchDefaultNucleobase();
|
|
144
141
|
|
|
145
|
-
const sequenceBaseInput = ui.
|
|
142
|
+
const sequenceBaseInput = ui.input.choice('Sequence basis', {value: defaultNucleotideBase, items: availableNucleoBases});
|
|
146
143
|
|
|
147
144
|
sequenceBaseInput.onInput(() => this.eventBus.replaceSequenceBase(sequenceBaseInput.value!));
|
|
148
145
|
|
|
@@ -155,10 +152,7 @@ export class PatternEditControlsManager {
|
|
|
155
152
|
}
|
|
156
153
|
|
|
157
154
|
private createPatternCommentInput(): StringInput {
|
|
158
|
-
const patternCommentInput = ui.
|
|
159
|
-
'Comment',
|
|
160
|
-
this.eventBus.getComment()
|
|
161
|
-
);
|
|
155
|
+
const patternCommentInput = ui.input.textArea('Comment', {value: this.eventBus.getComment()});
|
|
162
156
|
|
|
163
157
|
$(patternCommentInput.root).addClass('st-pattern-text-input');
|
|
164
158
|
|
|
@@ -174,10 +168,7 @@ export class PatternEditControlsManager {
|
|
|
174
168
|
}
|
|
175
169
|
|
|
176
170
|
private createPatternNameInputBlock(): HTMLElement {
|
|
177
|
-
const patternNameInput = ui.
|
|
178
|
-
'Pattern name',
|
|
179
|
-
this.eventBus.getPatternName()
|
|
180
|
-
);
|
|
171
|
+
const patternNameInput = ui.input.textArea('Pattern name', {value: this.eventBus.getPatternName()});
|
|
181
172
|
|
|
182
173
|
$(patternNameInput.root).addClass('st-pattern-text-input');
|
|
183
174
|
|
|
@@ -93,14 +93,12 @@ export class PatternLoadControlsManager {
|
|
|
93
93
|
if (this.dataManager.getOtherUsersPatternNames().length > 0)
|
|
94
94
|
possibleValues.push(this.dataManager.getOtherUsersAuthorshipCategory());
|
|
95
95
|
|
|
96
|
-
const authorChoiceInput = ui.
|
|
97
|
-
'Author',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
this.eventBus.selectAuthor(userName);
|
|
103
|
-
}
|
|
96
|
+
const authorChoiceInput = ui.input.choice(
|
|
97
|
+
'Author', {value: this.eventBus.getSelectedAuthor(), items: possibleValues,
|
|
98
|
+
onValueChanged: (input) => {
|
|
99
|
+
this.authorSelectedByUser = true;
|
|
100
|
+
this.eventBus.selectAuthor(input.value);
|
|
101
|
+
}}
|
|
104
102
|
);
|
|
105
103
|
this.setAuthorChoiceInputStyle(authorChoiceInput);
|
|
106
104
|
authorChoiceInput.setTooltip('Select pattern author');
|
|
@@ -132,7 +130,7 @@ export class PatternLoadControlsManager {
|
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
const defaultValue = this.getPatternName(patternList);
|
|
135
|
-
const choiceInput = ui.
|
|
133
|
+
const choiceInput = ui.input.choice('Pattern', {value: defaultValue, items: patternList});
|
|
136
134
|
choiceInput.setTooltip('Select pattern to load');
|
|
137
135
|
|
|
138
136
|
$(choiceInput.input).css({
|
|
@@ -44,11 +44,10 @@ export class NumericLabelVisibilityControls {
|
|
|
44
44
|
|
|
45
45
|
private createSingleInput(nucleotide: string): BooleanInput {
|
|
46
46
|
const initialValue = this.eventBus.getModificationsWithNumericLabels().includes(nucleotide);
|
|
47
|
-
const input = ui.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
);
|
|
47
|
+
const input = ui.input.bool(nucleotide, {
|
|
48
|
+
value: initialValue,
|
|
49
|
+
onValueChanged: (input) => this.handleNumericLabelToggle(nucleotide, input.value)
|
|
50
|
+
});
|
|
52
51
|
$(input.root).css('padding-right', '20px');
|
|
53
52
|
|
|
54
53
|
input.setTooltip(`Show numeric labels for ${nucleotide}`);
|
|
@@ -43,7 +43,7 @@ export class HeaderControls {
|
|
|
43
43
|
private createAllPtoActivationInput(): BooleanInput {
|
|
44
44
|
const flags = this.initialPatternConfig.phosphorothioateLinkageFlags;
|
|
45
45
|
const initialValue = this.areAllPtoLinkagesSet(flags);
|
|
46
|
-
const allPtoActivationInput = ui.
|
|
46
|
+
const allPtoActivationInput = ui.input.bool('All PTO', {value: initialValue});
|
|
47
47
|
|
|
48
48
|
allPtoActivationInput.onInput(() => {
|
|
49
49
|
const value = allPtoActivationInput.value!;
|
|
@@ -79,7 +79,7 @@ export class HeaderControls {
|
|
|
79
79
|
if (!this.eventBus.isAntisenseStrandActive() && strand === STRAND.ANTISENSE)
|
|
80
80
|
return;
|
|
81
81
|
const initialValue = this.isFirstPtoActive(strand);
|
|
82
|
-
const firstPtoInput = ui.
|
|
82
|
+
const firstPtoInput = ui.input.bool(`First ${strand} PTO`, {value: initialValue});
|
|
83
83
|
|
|
84
84
|
firstPtoInput.onInput(() => {
|
|
85
85
|
const value = firstPtoInput.value!;
|
|
@@ -78,7 +78,7 @@ export class StrandControls {
|
|
|
78
78
|
);
|
|
79
79
|
const nucleotides = this.eventBus.getNucleotideSequences()[strand];
|
|
80
80
|
const choiceInputs = nucleotides.map((nucleotide, index) => {
|
|
81
|
-
const input = ui.
|
|
81
|
+
const input = ui.input.choice<string>('', {value: nucleotide, items: nucleotideBaseChoices});
|
|
82
82
|
input.onInput(() => {
|
|
83
83
|
const newValue = input.value!;
|
|
84
84
|
this.eventBus.setNucleotide(strand, index, newValue);
|
|
@@ -92,7 +92,7 @@ export class StrandControls {
|
|
|
92
92
|
private createPTOFlagInputs(strand: StrandType): BooleanInput[] {
|
|
93
93
|
const ptoLinkageFlags = this.eventBus.getPhosphorothioateLinkageFlags()[strand].slice(1);
|
|
94
94
|
const ptoLinkageInputs = ptoLinkageFlags.map((flag, index) => {
|
|
95
|
-
const input = ui.
|
|
95
|
+
const input = ui.input.bool('', {value: flag});
|
|
96
96
|
input.onInput(() => {
|
|
97
97
|
const newValue = input.value!;
|
|
98
98
|
this.eventBus.setPhosphorothioateLinkageFlag(strand, index + 1, newValue);
|
|
@@ -106,7 +106,7 @@ class StrandTerminalModificationControls {
|
|
|
106
106
|
|
|
107
107
|
private createInputForTerminus(strand: StrandType, terminus: TERMINUS): StringInput {
|
|
108
108
|
const initialValue = this.eventBus.getTerminalModifications()[strand][terminus];
|
|
109
|
-
const input = ui.
|
|
109
|
+
const input = ui.input.textArea(terminus, {value: initialValue});
|
|
110
110
|
this.applyStylingToInput(input);
|
|
111
111
|
|
|
112
112
|
input.onInput(() => {
|
|
@@ -33,11 +33,11 @@ class StructureAppLayout {
|
|
|
33
33
|
this.onInvalidInput = new rxjs.Subject<string>();
|
|
34
34
|
this.inputBase = Object.fromEntries(
|
|
35
35
|
STRANDS.map(
|
|
36
|
-
(key) => [key, ui.
|
|
36
|
+
(key) => [key, ui.input.textArea('', {value: '', onValueChanged: () => { this.onInput.next(); }})]
|
|
37
37
|
)
|
|
38
38
|
);
|
|
39
|
-
this.useChiralInput = ui.
|
|
40
|
-
this.saveAllStrandsInput = ui.
|
|
39
|
+
this.useChiralInput = ui.input.bool('Use chiral', {value: true});
|
|
40
|
+
this.saveAllStrandsInput = ui.input.bool('Save as one entity', {value: true});
|
|
41
41
|
ui.tooltip.bind(this.saveAllStrandsInput.root, 'Save SDF with all strands in one molfile');
|
|
42
42
|
this.directionInversion = Object.fromEntries(
|
|
43
43
|
STRANDS.map((key) => [key, false])
|
|
@@ -102,8 +102,8 @@ class StructureAppLayout {
|
|
|
102
102
|
STRANDS.map(
|
|
103
103
|
(key, idx) => {
|
|
104
104
|
const selected = (idx === 0) ? DIRECTION.STRAIGHT : DIRECTION.INVERSE;
|
|
105
|
-
return [key, ui.
|
|
106
|
-
`${key.toUpperCase()} direction`, selected, [DIRECTION.STRAIGHT, DIRECTION.INVERSE]
|
|
105
|
+
return [key, ui.input.choice(
|
|
106
|
+
`${key.toUpperCase()} direction`, {value: selected, items: [DIRECTION.STRAIGHT, DIRECTION.INVERSE]}
|
|
107
107
|
)];
|
|
108
108
|
}
|
|
109
109
|
)
|
|
@@ -47,13 +47,12 @@ class TranslatorAppLayout {
|
|
|
47
47
|
this.moleculeImgDiv.style.marginTop = '12px';
|
|
48
48
|
|
|
49
49
|
this.outputTableDiv = ui.div([]);
|
|
50
|
-
this.formatChoiceInput = ui.
|
|
50
|
+
this.formatChoiceInput = ui.input.choice('', {value: DEFAULT_FORMATS.HELM, items: this.inputFormats, onValueChanged: async () => {
|
|
51
51
|
this.format = this.formatChoiceInput.value;
|
|
52
52
|
this.updateTable();
|
|
53
53
|
await this.updateMolImg();
|
|
54
|
-
});
|
|
55
|
-
this.sequenceInputBase = ui.
|
|
56
|
-
() => { this.onInput.next(); });
|
|
54
|
+
}});
|
|
55
|
+
this.sequenceInputBase = ui.input.textArea('', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }});
|
|
57
56
|
|
|
58
57
|
this.init();
|
|
59
58
|
|
|
@@ -100,18 +99,12 @@ class TranslatorAppLayout {
|
|
|
100
99
|
|
|
101
100
|
const tableControlsManager = new TableControlsManager(this.eventBus);
|
|
102
101
|
const tableControls = tableControlsManager.createUIComponents();
|
|
103
|
-
const inputFormats = ui.
|
|
104
|
-
|
|
105
|
-
DEFAULT_FORMATS.AXOLABS,
|
|
106
|
-
this.inputFormats,
|
|
107
|
-
(value: string) => this.eventBus.selectInputFormat(value)
|
|
102
|
+
const inputFormats = ui.input.choice('Input format', {value: DEFAULT_FORMATS.AXOLABS,
|
|
103
|
+
items: this.inputFormats, onValueChanged: (input) => this.eventBus.selectInputFormat(input.value)}
|
|
108
104
|
);
|
|
109
105
|
|
|
110
|
-
const outputFormats = ui.
|
|
111
|
-
|
|
112
|
-
NUCLEOTIDES_FORMAT,
|
|
113
|
-
getSupportedTargetFormats(this.th),
|
|
114
|
-
(value: string) => this.eventBus.selectOutputFormat(value)
|
|
106
|
+
const outputFormats = ui.input.choice('Output format', {value: NUCLEOTIDES_FORMAT,
|
|
107
|
+
items: getSupportedTargetFormats(this.th), onValueChanged: (input) => this.eventBus.selectOutputFormat(input.value)}
|
|
115
108
|
);
|
|
116
109
|
const convertBulkButton = this.createConvertBulkButton();
|
|
117
110
|
|
|
@@ -169,7 +162,7 @@ class TranslatorAppLayout {
|
|
|
169
162
|
if (outputFormat === NUCLEOTIDES_FORMAT || outputFormat === DEFAULT_FORMATS.HELM) {
|
|
170
163
|
translatedColumn.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
171
164
|
const units = outputFormat == NUCLEOTIDES_FORMAT ? NOTATION.FASTA : NOTATION.HELM;
|
|
172
|
-
translatedColumn.
|
|
165
|
+
translatedColumn.meta.units = units;
|
|
173
166
|
const seqHandler = SeqHandler.forColumn(translatedColumn as DG.Column<string>);
|
|
174
167
|
const setUnits = outputFormat == NUCLEOTIDES_FORMAT ? SeqHandler.setUnitsToFastaColumn :
|
|
175
168
|
SeqHandler.setUnitsToHelmColumn;
|
|
@@ -381,16 +374,13 @@ class TableInputManager {
|
|
|
381
374
|
private createTableInput(): DG.InputBase<DG.DataFrame | null> {
|
|
382
375
|
const currentlySelectedTable = this.eventBus.getSelectedTable();
|
|
383
376
|
|
|
384
|
-
const tableInput = ui.
|
|
385
|
-
|
|
386
|
-
currentlySelectedTable,
|
|
387
|
-
this.availableTables,
|
|
388
|
-
(table: DG.DataFrame) => {
|
|
377
|
+
const tableInput = ui.input.table('Table', {value: currentlySelectedTable!, items: this.availableTables,
|
|
378
|
+
onValueChanged: (input) => {
|
|
389
379
|
// WARNING: non-null check necessary to prevent resetting columns to
|
|
390
380
|
// null upon handling onTableAdded
|
|
391
|
-
if (
|
|
392
|
-
this.eventBus.selectTable(
|
|
393
|
-
});
|
|
381
|
+
if (input.value !== null)
|
|
382
|
+
this.eventBus.selectTable(input.value);
|
|
383
|
+
}});
|
|
394
384
|
return tableInput;
|
|
395
385
|
}
|
|
396
386
|
|
|
@@ -459,10 +449,8 @@ class ColumnInputsManager {
|
|
|
459
449
|
const selectedColumnName = matchingColumnName ? matchingColumnName : columnNames[0];
|
|
460
450
|
this.selectColumnIfTableNotNull(selectedTable, selectedColumnName, columnLabel);
|
|
461
451
|
|
|
462
|
-
const input = ui.
|
|
463
|
-
|
|
464
|
-
selectedColumnName, columnNames,
|
|
465
|
-
(colName: string) => this.selectColumnIfTableNotNull(selectedTable, colName, columnLabel)
|
|
452
|
+
const input = ui.input.choice(`${columnLabel}`, {value: selectedColumnName, items: columnNames,
|
|
453
|
+
onValueChanged: (input) => this.selectColumnIfTableNotNull(selectedTable, input.value, columnLabel)}
|
|
466
454
|
);
|
|
467
455
|
|
|
468
456
|
return input;
|
package/src/package.ts
CHANGED
|
@@ -16,10 +16,12 @@ import {demoOligoPatternUI, demoOligoStructureUI, demoOligoTranslatorUI} from '.
|
|
|
16
16
|
import {getExternalAppViewFactories} from './plugins/mermade';
|
|
17
17
|
|
|
18
18
|
//polytool specific
|
|
19
|
-
import {getPolyToolConversionDialog
|
|
19
|
+
import {getPolyToolConversionDialog} from './polytool/pt-dialog';
|
|
20
20
|
import {_setPeptideColumn} from './polytool/utils';
|
|
21
21
|
import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
|
|
22
22
|
import {ITranslationHelper} from './types';
|
|
23
|
+
import {polyToolEnumerateHelmUI, polyToolEnumerateChemUI} from './polytool/pt-ui';
|
|
24
|
+
import {addContextMenuUI} from './utils/context-menu';
|
|
23
25
|
|
|
24
26
|
export const _package: OligoToolkitPackage = new OligoToolkitPackage();
|
|
25
27
|
|
|
@@ -163,19 +165,20 @@ export async function polyToolConvert(): Promise<void> {
|
|
|
163
165
|
}
|
|
164
166
|
}
|
|
165
167
|
|
|
166
|
-
//top-menu: Bio | Convert | PolyTool-Enumerate
|
|
167
|
-
//name:
|
|
168
|
+
//top-menu: Bio | Convert | PolyTool-Enumerate HELM
|
|
169
|
+
//name: polyToolEnumerateHelm
|
|
168
170
|
//description: Perform cyclization of polymers
|
|
169
|
-
export async function
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
dialog = await getPolyToolEnumerationDialog();
|
|
173
|
-
dialog.show();
|
|
174
|
-
} catch (err: any) {
|
|
175
|
-
grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
|
|
176
|
-
}
|
|
171
|
+
export async function polyToolEnumerateHelm(): Promise<void> {
|
|
172
|
+
polyToolEnumerateHelmUI();
|
|
177
173
|
}
|
|
178
174
|
|
|
175
|
+
// //top-menu: Bio | Convert | PolyTool-Enumerate Chem
|
|
176
|
+
// //name: polyToolEnumerateChem
|
|
177
|
+
// //description: Perform cyclization of polymers
|
|
178
|
+
// export async function polyToolEnumerateChem(): Promise<void> {
|
|
179
|
+
// polyToolEnumerateChemUI();
|
|
180
|
+
// }
|
|
181
|
+
|
|
179
182
|
//name: polyToolColumnChoice
|
|
180
183
|
//input: dataframe df [Input data table]
|
|
181
184
|
//input: column macroMolecule
|
|
@@ -194,3 +197,41 @@ export async function createMonomerLibraryForPolyTool(file: DG.FileInfo) {
|
|
|
194
197
|
const jsonFileContent = JSON.stringify(libObject, null, 2);
|
|
195
198
|
DG.Utils.download(jsonFileName, jsonFileContent);
|
|
196
199
|
}
|
|
200
|
+
|
|
201
|
+
// -- Handle context menu --
|
|
202
|
+
|
|
203
|
+
//name: addContextMenu
|
|
204
|
+
//input: object event
|
|
205
|
+
export function addContextMenu(event: DG.EventData): void {
|
|
206
|
+
addContextMenuUI(event);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// //name: PolyTool Converter
|
|
210
|
+
// //meta.icon: img/icons/structure.png
|
|
211
|
+
// //meta.browsePath: PolyTool
|
|
212
|
+
// //tags: app
|
|
213
|
+
// //output: view v
|
|
214
|
+
// export async function ptConverterApp(): Promise<DG.ViewBase> {
|
|
215
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
216
|
+
// return view;
|
|
217
|
+
// }
|
|
218
|
+
|
|
219
|
+
// //name: PolyTool Enumerator Helm
|
|
220
|
+
// //meta.icon: img/icons/structure.png
|
|
221
|
+
// //meta.browsePath: PolyTool
|
|
222
|
+
// //tags: app
|
|
223
|
+
// //output: view v
|
|
224
|
+
// export async function ptEnumeratorHelmApp(): Promise<DG.ViewBase> {
|
|
225
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
226
|
+
// return view;
|
|
227
|
+
// }
|
|
228
|
+
|
|
229
|
+
// //name: PolyTool Enumerator Chem
|
|
230
|
+
// //meta.icon: img/icons/structure.png
|
|
231
|
+
// //meta.browsePath: PolyTool
|
|
232
|
+
// //tags: app
|
|
233
|
+
// //output: view v
|
|
234
|
+
// export async function ptEnumeratorChemApp(): Promise<DG.ViewBase> {
|
|
235
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
236
|
+
// return view;
|
|
237
|
+
// }
|
package/src/plugins/mermade.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function getExternalAppViewFactories(
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function getMerMadeParameters(th: ITranslationHelper): { [name: string]: any } {
|
|
44
|
-
const base = ui.
|
|
44
|
+
const base = ui.input.textArea('', {value: ''});
|
|
45
45
|
const input = new ColoredTextInput(base, th.highlightInvalidSubsequence);
|
|
46
46
|
|
|
47
47
|
return {
|
|
@@ -10,7 +10,7 @@ export const RULES_DIMER = '(#2)';
|
|
|
10
10
|
export const RULES_HETERODIMER = '($2)';
|
|
11
11
|
|
|
12
12
|
function addCommonTags(col: DG.Column): void {
|
|
13
|
-
col.
|
|
13
|
+
col.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
14
14
|
col.setTag('aligned', ALIGNMENT.SEQ);
|
|
15
15
|
col.setTag('alphabet', ALPHABET.PT);
|
|
16
16
|
}
|
|
@@ -290,7 +290,7 @@ export async function addTransformedColumn(
|
|
|
290
290
|
const targetHelmCol = DG.Column.fromList('string', helmColName, targetList);
|
|
291
291
|
|
|
292
292
|
addCommonTags(targetHelmCol);
|
|
293
|
-
targetHelmCol.
|
|
293
|
+
targetHelmCol.meta.units = NOTATION.HELM;
|
|
294
294
|
|
|
295
295
|
if (addHelm) {
|
|
296
296
|
targetHelmCol.setTag('cell.renderer', 'helm');
|