@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.
Files changed (33) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/detectors.js +32 -0
  3. package/dist/package-test.js +1 -1
  4. package/dist/package-test.js.map +1 -1
  5. package/dist/package.js +1 -1
  6. package/dist/package.js.map +1 -1
  7. package/package.json +10 -6
  8. package/src/apps/common/view/components/colored-input/style.css +3 -2
  9. package/src/apps/pattern/model/data-manager.ts +4 -1
  10. package/src/apps/pattern/model/translator.ts +45 -8
  11. package/src/apps/pattern/view/components/bulk-convert/column-input.ts +4 -10
  12. package/src/apps/pattern/view/components/bulk-convert/table-input.ts +5 -8
  13. package/src/apps/pattern/view/components/edit-block-controls.ts +6 -15
  14. package/src/apps/pattern/view/components/load-block-controls.ts +7 -9
  15. package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +4 -5
  16. package/src/apps/pattern/view/components/strand-editor/header-controls.ts +2 -2
  17. package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +2 -2
  18. package/src/apps/pattern/view/components/terminal-modification-editor.ts +1 -1
  19. package/src/apps/pattern/view/components/translation-examples-block.ts +1 -1
  20. package/src/apps/structure/view/ui.ts +5 -5
  21. package/src/apps/translator/view/ui.ts +15 -27
  22. package/src/package.ts +52 -11
  23. package/src/plugins/mermade.ts +1 -1
  24. package/src/polytool/pt-conversion.ts +2 -2
  25. package/src/polytool/pt-dialog.ts +99 -18
  26. package/src/polytool/pt-enumeration-chem.ts +105 -0
  27. package/src/polytool/pt-enumeration-helm.ts +22 -0
  28. package/src/polytool/pt-ui.ts +25 -0
  29. package/src/polytool/utils.ts +34 -3
  30. package/src/utils/context-menu.ts +57 -0
  31. package/src/utils/err-info.ts +13 -0
  32. package/webpack.config.js +2 -4
  33. 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.5",
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": "^5.41.9",
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.6",
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.18.6",
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/bio": "^2.12.23",
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 Mono', 'Roboto Mono Local', monospace;
23
- font-size: 12px;
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
- const userFriendlyName = (await grok.dapi.users.find(authorID)).friendlyName;
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 strandColNames = STRANDS.filter(
14
+ const strandInputData = STRANDS.filter(
15
15
  (strand) => !(strand === STRAND.ANTISENSE && !eventBus.isAntisenseStrandActive())
16
- ).map((strand) => eventBus.getSelectedStrandColumn(strand))
17
- .filter((colName) => colName) as string[];
18
-
19
- if (strandColNames.length === 0) {
20
- grok.shell.warning('Please column for sense strand');
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 strandCols = strandColNames.map((colName) => df.getCol(colName));
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.choiceInput(
57
- `${STRAND_LABEL[strand]} column`,
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.choiceInput(
71
- 'ID column',
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.tableInput(
67
- 'Tables',
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 (table !== null && table instanceof DG.DataFrame)
74
- this.eventBus.selectTable(table);
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.switchInput(
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.intInput(
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.choiceInput('Sequence basis', defaultNucleotideBase, availableNucleoBases);
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.textInput(
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.textInput(
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.choiceInput(
97
- 'Author',
98
- this.eventBus.getSelectedAuthor(),
99
- possibleValues,
100
- (userName: string) => {
101
- this.authorSelectedByUser = true;
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.choiceInput('Pattern', defaultValue, patternList);
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.boolInput(
48
- nucleotide,
49
- initialValue,
50
- (value: boolean) => this.handleNumericLabelToggle(nucleotide, value)
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.boolInput('All PTO', initialValue);
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.boolInput(`First ${strand} PTO`, initialValue);
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.choiceInput<string>('', nucleotide, nucleotideBaseChoices);
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.boolInput('', flag);
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.textInput(terminus, initialValue);
109
+ const input = ui.input.textArea(terminus, {value: initialValue});
110
110
  this.applyStylingToInput(input);
111
111
 
112
112
  input.onInput(() => {
@@ -125,7 +125,7 @@ class StrandExample {
125
125
  }
126
126
 
127
127
  private createTextInputForExamples(): StringInput {
128
- const input = ui.textInput('', '');
128
+ const input = ui.input.textArea('', {value: ''});
129
129
  this.applyStylingToInput(input);
130
130
 
131
131
  return input;
@@ -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.textInput('', '', () => { this.onInput.next(); })]
36
+ (key) => [key, ui.input.textArea('', {value: '', onValueChanged: () => { this.onInput.next(); }})]
37
37
  )
38
38
  );
39
- this.useChiralInput = ui.boolInput('Use chiral', true);
40
- this.saveAllStrandsInput = ui.boolInput('Save as one entity', true);
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.choiceInput(
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.choiceInput('', DEFAULT_FORMATS.HELM, this.inputFormats, async () => {
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.textInput('', DEFAULT_AXOLABS_INPUT,
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.choiceInput(
104
- 'Input format',
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.choiceInput(
111
- 'Output format',
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.setTag(DG.TAGS.UNITS, units);
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.tableInput(
385
- 'Table',
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 (table !== null && table instanceof DG.DataFrame)
392
- this.eventBus.selectTable(table);
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.choiceInput(
463
- `${columnLabel}`,
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, getPolyToolEnumerationDialog} from './polytool/pt-dialog';
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: polyToolEnumerate
168
+ //top-menu: Bio | Convert | PolyTool-Enumerate HELM
169
+ //name: polyToolEnumerateHelm
168
170
  //description: Perform cyclization of polymers
169
- export async function polyToolEnumerate(): Promise<void> {
170
- let dialog: DG.Dialog;
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
+ // }
@@ -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.textInput('', '');
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.setTag('quality', DG.SEMTYPE.MACROMOLECULE);
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.setTag('units', NOTATION.HELM);
293
+ targetHelmCol.meta.units = NOTATION.HELM;
294
294
 
295
295
  if (addHelm) {
296
296
  targetHelmCol.setTag('cell.renderer', 'helm');