@datagrok/helm 2.3.1 → 2.3.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
3
  "friendlyName": "Helm",
4
- "version": "2.3.1",
4
+ "version": "2.3.2",
5
5
  "author": {
6
6
  "name": "Oleksandra Serhiienko",
7
7
  "email": "oserhiienko@datagrok.ai"
@@ -16,24 +16,25 @@
16
16
  "css/helm.css"
17
17
  ],
18
18
  "dependencies": {
19
- "@datagrok-libraries/bio": "^5.42.3",
19
+ "@datagrok-libraries/bio": "^5.42.5",
20
20
  "@datagrok-libraries/chem-meta": "^1.2.5",
21
- "@datagrok-libraries/utils": "^4.2.11",
21
+ "@datagrok-libraries/utils": "^4.2.13",
22
22
  "cash-dom": "^8.1.1",
23
- "datagrok-api": "^1.18.6",
23
+ "datagrok-api": "^1.20.0",
24
24
  "dayjs": "^1.10.6",
25
25
  "rxjs": "^6.5.5",
26
26
  "wu": "latest"
27
27
  },
28
28
  "devDependencies": {
29
- "@datagrok-libraries/helm-web-editor": "^1.1.5",
30
- "@datagrok-libraries/js-draw-lite": "^0.0.3",
29
+ "@datagrok-libraries/helm-web-editor": "^1.1.6",
30
+ "@datagrok-libraries/js-draw-lite": "^0.0.4",
31
31
  "@datagrok/bio": "^2.13.3",
32
32
  "@datagrok/chem": "^1.9.2",
33
33
  "@types/node": "17.0.45",
34
34
  "@types/wu": "latest",
35
35
  "@typescript-eslint/eslint-plugin": "^5.11.0",
36
36
  "@typescript-eslint/parser": "^5.11.0",
37
+ "datagrok-tools": "latest",
37
38
  "eslint": "^8.18.0",
38
39
  "eslint-config-google": "^0.14.0",
39
40
  "path": "^0.12.7",
@@ -4,14 +4,13 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {HelmType, Mol} from '@datagrok-libraries/bio/src/helm/types';
7
+ import {HelmType, ISeqMonomer, Mol} from '@datagrok-libraries/bio/src/helm/types';
8
8
 
9
- import {printLeftOrCentered} from '@datagrok-libraries/bio/src/utils/cell-renderer';
10
9
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
11
10
  import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
12
11
 
13
12
  import {findMonomers, parseHelm, removeGapsFromHelm} from './utils';
14
- import {HelmMonomerPlacer, ISeqMonomer} from './helm-monomer-placer';
13
+ import {HelmMonomerPlacer} from './helm-monomer-placer';
15
14
  import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol} from './utils/get-hovered';
16
15
  import {JSDraw2HelmModule} from './types';
17
16
 
@@ -54,7 +53,7 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
54
53
  let seqMonomer: ISeqMonomer | null;
55
54
  let missedMonomers: Set<string> = new Set<string>(); // of .size = 0
56
55
  if (editorMol)
57
- seqMonomer = getHoveredMonomerFromEditorMol(argsX, argsY, gridCell, editorMol);
56
+ seqMonomer = getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
58
57
  else {
59
58
  const seq: string = !gridCell.cell.value ? '' : removeGapsFromHelm(gridCell.cell.value as string);
60
59
  const monomerList = parseHelm(seq);
@@ -3,21 +3,23 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {
6
- App, Atom, HelmType, GetMonomerFunc, GetMonomerResType
6
+ App, Atom, HelmType, GetMonomerFunc, GetMonomerResType, HelmString, HelmMol
7
7
  } from '@datagrok-libraries/bio/src/helm/types';
8
8
 
9
9
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
10
10
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
11
- import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
11
+ import {IHelmHelper, IInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
12
  import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
13
13
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
14
14
 
15
15
  import {HelmWebEditor} from './helm-web-editor';
16
16
  import {OrgHelmModule, ScilModule} from './types';
17
17
  import {getWebEditorMonomer} from './utils/get-monomer';
18
+ import {HelmInput} from './widgets/helm-input';
18
19
 
19
20
  import {_package} from './package';
20
21
 
22
+
21
23
  declare const scil: ScilModule;
22
24
  declare const org: OrgHelmModule;
23
25
 
@@ -32,8 +34,19 @@ export class HelmHelper implements IHelmHelper {
32
34
  throw new Error(`HelmHelper must be a single.`);
33
35
  }
34
36
 
35
- createHelmWebEditor(): IHelmWebEditor {
36
- return new HelmWebEditor();
37
+ createHelmInput(name?: string, options?: IInputInitOptions<HelmMol>): DG.InputBase<HelmMol> {
38
+ try {
39
+ const monomerLib: IMonomerLib = _package.libHelper.getBioLib();
40
+ return HelmInput.create(this, monomerLib, name, options);
41
+ } catch (err: any) {
42
+ const [errMsg, errStack] = errInfo(err);
43
+ this.logger.error(`Helm: HelmHelper.createHelmInput(), Error: ${errMsg}`, undefined, errStack);
44
+ throw err;
45
+ }
46
+ }
47
+
48
+ createHelmWebEditor(host?: HTMLDivElement): IHelmWebEditor {
49
+ return new HelmWebEditor(host);
37
50
  }
38
51
 
39
52
  createWebEditorApp(host: HTMLDivElement, helm: string): App {
@@ -12,11 +12,6 @@ import {getParts, parseHelm} from './utils';
12
12
 
13
13
  import {_package, getMonomerLib} from './package';
14
14
 
15
- export interface ISeqMonomer {
16
- polymerType: PolymerType;
17
- symbol: string;
18
- }
19
-
20
15
  export class HelmMonomerPlacer extends CellRendererBackBase<string> {
21
16
  private _allPartsList: (string[] | null)[];
22
17
  private _lengthsList: (number[] | null)[];
@@ -2,12 +2,17 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
+ import {Unsubscribable} from 'rxjs';
6
+
7
+ import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
5
8
  import {
6
9
  App, Editor, HelmType, IHelmWebEditor
7
10
  } from '@datagrok-libraries/bio/src/helm/types';
8
11
 
9
12
  import {JSDraw2HelmModule, OrgHelmModule, ScilModule} from './types';
10
13
 
14
+ import {_package} from './package';
15
+
11
16
  declare const scil: ScilModule;
12
17
  declare const JSDraw2: JSDraw2HelmModule;
13
18
  declare const org: OrgHelmModule;
@@ -18,10 +23,27 @@ export class HelmWebEditor implements IHelmWebEditor {
18
23
 
19
24
  w = 200;
20
25
  h = 100;
26
+ private subs: Unsubscribable[];
21
27
 
22
- constructor() {
23
- this.host = ui.div([], {style: {width: `${this.w}px`, height: `${this.h}px`}});
28
+ constructor(
29
+ host?: HTMLDivElement,
30
+ private logger: ILogger = _package.logger
31
+ ) {
32
+ this.host = host ?? ui.div([], {style: {width: `${this.w}px`, height: `${this.h}px`}});
24
33
  this.editor = new JSDraw2.Editor(this.host, {width: this.w, height: this.h, viewonly: true});
34
+
35
+ this.subs = [];
36
+ this.subs.push(ui.onSizeChanged(this.host).subscribe(this.hostOnSizeChanged.bind(this)));
37
+ }
38
+
39
+ protected toLog(): string {
40
+ return `Helm: HelmWebEditor<#>`;
41
+ }
42
+
43
+ private hostOnSizeChanged(_: any): void {
44
+ const logPrefix = `${this.toLog()}.hostOnSizeChanged()`;
45
+ this.logger.debug(`${logPrefix}`);
46
+ this.editor.setSize(this.host.clientWidth, this.host.clientHeight);
25
47
  }
26
48
 
27
49
  resizeEditor(w: number, h: number) {
@@ -8,6 +8,7 @@ import * as grok from 'datagrok-api/grok';
8
8
  import {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';
9
9
  import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
10
 
11
+ import './tests/_first-tests';
11
12
  import './tests/helm-tests';
12
13
  import './tests/findMonomers-tests';
13
14
  import './tests/helm-service-tests';
@@ -18,6 +19,7 @@ import './tests/get-all-parts-tests';
18
19
  import './tests/get-monomer-tests';
19
20
  import './tests/parse-helm-tests';
20
21
  import './tests/helm-web-editor-tests';
22
+ import './tests/helm-input-tests';
21
23
 
22
24
  export const _package = new DG.Package();
23
25
  export {tests};
@@ -9,6 +9,8 @@ import type {
9
9
  } from '@datagrok-libraries/bio/src/helm/types';
10
10
  import {HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
11
11
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
12
+ import {LoggerWrapper} from '@datagrok-libraries/bio/src/utils/logger';
13
+ import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
12
14
 
13
15
  import {HelmHelper} from './helm-helper';
14
16
  import {HelmService} from './utils/helm-service';
@@ -48,8 +50,10 @@ export async function initHelmLoadAndPatchDojo(): Promise<void> {
48
50
  // {module: 'dojo.request.iframe', checker: () => !!dojo?.request?.iframe},
49
51
  {module: 'dojo.dom', checker: () => !!dojo?.dom},
50
52
  {module: 'dojox.gfx', checker: () => !!dojox?.gfx},
51
- {module: 'dojox.gfx.svg', checker: () => !!dojox?.gfx?.svg},
53
+ {module: 'dojox.gfx.svg', checker: () => !!dojox?.gfx?.svg && !!dojox?.gfx?.createSurface},
52
54
  {module: 'dojox.gfx.shape', checker: () => !!dojox?.gfx?.shape},
55
+ // {module: 'dojox.storage.Provider', checker: () => !!dojox?.storage?.Provider},
56
+ // {module: 'dojox.storage.LocalStorageProvider', checker: () => !!dojox?.storage?.LocalStorageProvider},
53
57
  ];
54
58
  for (const dojoTarget of dojoTargetList) {
55
59
  try { dojo.require(dojoTarget.module); } catch (err: any) {
@@ -111,11 +115,19 @@ export const helmJsonReplacer = (key: string, value: any): any => {
111
115
 
112
116
  export class HelmPackage extends DG.Package {
113
117
  public alertOriginal: (s: string) => void;
114
- public readonly hh: HelmHelper;
118
+ public readonly helmHelper: HelmHelper;
119
+ public libHelper: IMonomerLibHelper;
115
120
 
116
- constructor() {
121
+ constructor(opts: { debug: boolean } = {debug: false}) {
117
122
  super();
118
- this.hh = new HelmHelper(this.logger);
123
+ // @ts-ignore
124
+ super._logger = new LoggerWrapper(super.logger, opts.debug);
125
+
126
+ this.helmHelper = new HelmHelper(this.logger);
127
+ }
128
+
129
+ setLibHelper(libHelper: IMonomerLibHelper) {
130
+ this.libHelper = libHelper;
119
131
  }
120
132
 
121
133
  public initHelmPatchScilAlert(): void {
@@ -133,7 +145,7 @@ export class HelmPackage extends DG.Package {
133
145
 
134
146
  this.logger.debug(`${logPrefix}, this.getMonomerOriginal stored`);
135
147
 
136
- this.hh.overrideGetMonomer(this.hh.buildGetMonomerFromLib(monomerLib));
148
+ this.helmHelper.overrideGetMonomer(this.helmHelper.buildGetMonomerFromLib(monomerLib));
137
149
 
138
150
  // @ts-ignore, intercept with proxy to observe access and usage
139
151
  org.helm.webeditor.Monomers = new class {
package/src/package.ts CHANGED
@@ -11,8 +11,8 @@ import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
11
11
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
12
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
13
13
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
14
- import {App, HweWindow} from '@datagrok-libraries/bio/src/helm/types';
15
- import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
14
+ import {App, HelmMol, HweWindow} from '@datagrok-libraries/bio/src/helm/types';
15
+ import {IHelmHelper, IInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
16
16
  import {HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
17
17
  import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
18
18
 
@@ -28,7 +28,7 @@ import {getRS} from './utils/get-monomer-dummy';
28
28
  import {buildWebEditorApp} from './helm-web-editor';
29
29
  import {JSDraw2HelmModule, OrgHelmModule, ScilModule} from './types';
30
30
 
31
- export const _package = new HelmPackage();
31
+ export const _package = new HelmPackage({debug: false});
32
32
 
33
33
  let monomerLib: IMonomerLib | null = null;
34
34
 
@@ -53,11 +53,6 @@ export async function initHelm(): Promise<void> {
53
53
  try {
54
54
  const [_, lib]: [void, IMonomerLib] = await Promise.all([
55
55
  Promise.all([
56
- new Promise<void>((resolve, reject) => {
57
- // @ts-ignore
58
- // try { dojo.ready(function() { resolve(null); }); } catch (err: any) { reject(err); }
59
- resolve();
60
- }),
61
56
  (async () => {
62
57
  _package.logger.debug(`${logPrefix}, dependence loading …`);
63
58
  const t1: number = performance.now();
@@ -68,7 +63,7 @@ export async function initHelm(): Promise<void> {
68
63
 
69
64
  // Alternatively load old bundles by package.json/sources
70
65
  _package.logger.debug(`${logPrefix}, HelmWebEditor awaiting …`);
71
- require('vendor/helm-web-editor'); // through webpack.config.ts/alias
66
+ require('../node_modules/@datagrok-libraries/helm-web-editor/dist/package.js');
72
67
  await window.helmWebEditor$.initPromise;
73
68
  _package.logger.debug(`${logPrefix}, HelmWebEditor loaded`);
74
69
 
@@ -86,6 +81,7 @@ export async function initHelm(): Promise<void> {
86
81
  }),
87
82
  (async () => {
88
83
  const libHelper = await getMonomerLibHelper();
84
+ _package.setLibHelper(libHelper);
89
85
  return libHelper.getBioLib();
90
86
  })()
91
87
  ]);
@@ -175,12 +171,12 @@ export function openEditor(mol: string): void {
175
171
  const df = grok.shell.tv.grid.dataFrame;
176
172
  const col = df.columns.bySemType('Macromolecule')! as DG.Column<string>;
177
173
  const colSh = SeqHandler.forColumn(col);
178
- const colUnits = col.getTag(DG.TAGS.UNITS);
174
+ const colUnits = col.meta.units;
179
175
  if (colUnits === NOTATION.HELM)
180
176
  checkMonomersAndOpenWebEditor(df.currentCell, undefined, undefined);
181
177
  const convert = colSh.getConverter(NOTATION.HELM);
182
178
  const helmMol = convert(mol);
183
- checkMonomersAndOpenWebEditor(df.currentCell, helmMol, col.getTag(DG.TAGS.UNITS));
179
+ checkMonomersAndOpenWebEditor(df.currentCell, helmMol, col.meta.units!);
184
180
  }
185
181
 
186
182
  //name: Properties
@@ -248,12 +244,26 @@ export function getMolfiles(col: DG.Column): DG.Column {
248
244
  }
249
245
  }
250
246
 
247
+ // -- Inputs --
248
+
249
+ //name: helmInput
250
+ //tags: valueEditor
251
+ //meta.propertyType: string
252
+ //meta.semType: Macromolecule
253
+ //input: string name =undefined {optional: true}
254
+ //input: object options =undefined {optional: true}
255
+ //output: object result
256
+ export function helmInput(name: string, options: IInputInitOptions<HelmMol>): DG.InputBase<HelmMol> {
257
+ // TODO: Annotate for semType = 'Macromolecule' AND units = 'helm'
258
+ return _package.helmHelper.createHelmInput(name, options);
259
+ }
260
+
251
261
  // -- Utils --
252
262
 
253
263
  //name: getHelmHelper
254
264
  //output: object result
255
265
  export async function getHelmHelper(): Promise<IHelmHelper> {
256
- return _package.hh;
266
+ return _package.helmHelper;
257
267
  }
258
268
 
259
269
  //name: measureCellRenderer
@@ -0,0 +1,10 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {category, test} from '@datagrok-libraries/utils/src/test';
6
+
7
+ category('_first', () => {
8
+ /** The first test of the package to evaluate problems with imports. */
9
+ test('_first', async () => { });
10
+ });
@@ -0,0 +1,86 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import $ from 'cash-dom';
6
+
7
+ import {after, before, category, delay, expect, test, timeout} from '@datagrok-libraries/utils/src/test';
8
+ import {IHelmHelper, getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
+ import {
11
+ getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
12
+ } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
13
+ import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
14
+
15
+ import type {HelmInput} from '../widgets/helm-input';
16
+
17
+ category('HelmInput', () => {
18
+ let helmHelper: IHelmHelper;
19
+
20
+ let monomerLibHelper: IMonomerLibHelper;
21
+ /** Backup actual user's monomer libraries settings */
22
+ let userLibSettings: UserLibSettings;
23
+
24
+ before(async () => {
25
+ helmHelper = await getHelmHelper();
26
+
27
+ monomerLibHelper = await getMonomerLibHelper();
28
+ userLibSettings = await getUserLibSettings();
29
+
30
+ // Test 'helm' requires default monomer library loaded
31
+ await setUserLibSettingsForTests();
32
+ await monomerLibHelper.awaitLoaded();
33
+ await monomerLibHelper.loadLibraries(true); // load default libraries
34
+ });
35
+
36
+ after(async () => {
37
+ await setUserLibSettings(userLibSettings);
38
+ await monomerLibHelper.loadLibraries(true); // load user settings libraries
39
+ });
40
+
41
+ test('inDialog', async () => {
42
+ const helmValue = 'PEPTIDE1{[meY].A.G.T}$$$$';
43
+ const helmInput = await ui.input.helmAsync('Macromolecule');
44
+ helmInput.stringValue = helmValue;
45
+ const dlg = ui.dialog('Helm Input Test')
46
+ .add(helmInput)
47
+ .show();
48
+ await delay(500);
49
+
50
+ const mol = helmInput.value;
51
+ expect(mol.atoms.length, 4);
52
+ expect(mol.bonds.length, 3);
53
+ });
54
+
55
+ test('tooltip', async () => {
56
+ await _testTooltipOnHelmInput();
57
+ }, {timeout: 300000});
58
+ });
59
+
60
+ async function _testTooltipOnHelmInput(): Promise<void> {
61
+ const helmValue = 'PEPTIDE1{[meY].A.G.T}$$$$';
62
+ const helmInput = (await ui.input.helmAsync('Macromolecule')) as HelmInput;
63
+ helmInput.stringValue = helmValue;
64
+ const dlg = ui.dialog('Helm Input Test')
65
+ .add(helmInput)
66
+ .show();
67
+ const dialogInputEl = $(dlg.root)
68
+ .find('div.d4-dialog-contents > div.ui-input-helm > div.ui-input-editor').get(0);
69
+ expect(helmInput.getInput(), dialogInputEl);
70
+
71
+ const mon = {i: 0, elem: 'meY'};
72
+ const a = helmInput.value.atoms[mon.i];
73
+ const iEl = helmInput.getInput();
74
+ const iBcr = iEl.getBoundingClientRect();
75
+ const ev = new MouseEvent('mousemove', {
76
+ cancelable: true, bubbles: true, view: window, button: 0,
77
+ clientX: iBcr.left + a.p.x, clientY: iBcr.top + a.p.y
78
+ });
79
+ iEl.dispatchEvent(ev);
80
+ await delay(200);
81
+
82
+ const tooltipEl = $(document).find('body > div.d4-tooltip').get(0) as HTMLElement;
83
+ const elemDiv = $(tooltipEl).find('div > div.d4-flex-row.ui-div > div:nth-child(1)').get(0);
84
+ expect(tooltipEl.style.display != 'none', true);
85
+ expect(elemDiv?.innerText, mon.elem);
86
+ }
@@ -49,7 +49,7 @@ category('Helm', () => {
49
49
  // const df = DG.DataFrame.fromCsv(file);
50
50
  // const col = df.columns.byName('HELM string');
51
51
  // await grok.data.detectSemanticTypes(df);
52
- // expect(col.tags[DG.TAGS.UNITS], 'HELM');
52
+ // expect(col.meta.units, 'HELM');
53
53
  // });
54
54
 
55
55
  const complexMonomers = [
@@ -121,7 +121,7 @@ function testPropertiesDict(
121
121
  ) {
122
122
  const col = DG.Column.fromStrings('seq', [seq]) as DG.Column<string>;
123
123
  col.semType = DG.SEMTYPE.MACROMOLECULE;
124
- col.setTag(DG.TAGS.UNITS, units);
124
+ col.meta.units = units;
125
125
  if (separator) col.setTag(bioTAGS.separator, separator);
126
126
  if (alphabet) col.setTag(bioTAGS.alphabet, alphabet);
127
127
  const sh = SeqHandler.forColumn(col);
@@ -57,7 +57,7 @@ category('renderers', () => {
57
57
  }, 'Table view canvas not found', 100);
58
58
 
59
59
  expect(helmCol.semType, DG.SEMTYPE.MACROMOLECULE);
60
- expect(helmCol.getTag(DG.TAGS.UNITS), NOTATION.HELM);
60
+ expect(helmCol.meta.units, NOTATION.HELM);
61
61
  expect(helmCol.getTag(DG.TAGS.CELL_RENDERER), 'helm');
62
62
 
63
63
  const cellRendererErrorJson: string = helmCol.getTag(helmTAGS.cellRendererRenderError);
@@ -102,11 +102,6 @@ RNA1{d(A)p.d(C)p.d(G)p.d(U)p}|PEPTIDE1{I.H.A.N.T.Thr_PO3H2}$$$$,0,1
102
102
  }, 500);
103
103
  // TODO: Any error occurred become 'Cannot read properties of null (reading 'get$columns')' because of scatter plot
104
104
  //await testEvent(sp.onAfterDrawScene, () => {}, () => { sp.invalidateCanvas(); }, 200);
105
- await awaitGrid(view.grid, 500);
105
+ await awaitGrid(view.grid, 1000);
106
106
  }
107
107
  });
108
-
109
-
110
-
111
-
112
-
@@ -0,0 +1,13 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
6
+
7
+ import {_package} from '../package';
8
+
9
+ export function defaultErrorHandler(err: any): void {
10
+ const [errMsg, errStack] = errInfo(err);
11
+ _package.logger.error(errMsg, undefined, errStack);
12
+ grok.shell.error(errMsg);
13
+ }
@@ -2,14 +2,14 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
 
5
- import {HelmType, PolymerType, Atom, Mol} from '@datagrok-libraries/bio/src/helm/types';
5
+ import {HelmType, PolymerType, Atom, Mol, ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
6
6
 
7
7
  import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
8
8
 
9
- import {HelmMonomerPlacer, ISeqMonomer} from '../helm-monomer-placer';
9
+ import {HelmMonomerPlacer} from '../helm-monomer-placer';
10
10
 
11
11
  export function getHoveredMonomerFromEditorMol(
12
- argsX: number, argsY: number, gridCell: DG.GridCell, mol: Mol<HelmType>
12
+ argsX: number, argsY: number, mol: Mol<HelmType>, cellHeight? : number
13
13
  ): ISeqMonomer | null {
14
14
  let hoveredSeqMonomer: ISeqMonomer | null = null;
15
15
 
@@ -41,7 +41,7 @@ export function getHoveredMonomerFromEditorMol(
41
41
  if (firstDistance < secondDistance * 0.45)
42
42
  hoveredSeqMonomer = firstSeqMonomer;
43
43
  } else {
44
- if (firstDistance < 0.35 * gridCell.bounds.height)
44
+ if (cellHeight && firstDistance < 0.35 * cellHeight)
45
45
  hoveredSeqMonomer = firstSeqMonomer;
46
46
  }
47
47
  }
@@ -84,7 +84,7 @@ export function getHoveredMonomerFallback(
84
84
  }
85
85
 
86
86
  function getSeqMonomerFromHelmAtom(atom: Atom<HelmType>): ISeqMonomer {
87
- const polymerType = helmTypeToPolymerType(atom.bio.type);
87
+ const polymerType = helmTypeToPolymerType(atom.bio!.type);
88
88
  return {symbol: atom.elem, polymerType: polymerType};
89
89
  }
90
90
 
@@ -4,13 +4,12 @@ import * as ui from 'datagrok-api/ui';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {HelmType, Mol} from '@datagrok-libraries/bio/src/helm/types';
7
+ import {HelmType, ISeqMonomer, Mol} from '@datagrok-libraries/bio/src/helm/types';
8
8
  import {
9
9
  CellRendererBackAsyncBase, RenderServiceBase
10
10
  } from '@datagrok-libraries/bio/src/utils/cell-renderer-async-base';
11
11
  import {HelmAux, HelmProps} from '@datagrok-libraries/bio/src/viewers/helm-service';
12
12
 
13
- import {ISeqMonomer} from '../helm-monomer-placer';
14
13
  import {getHoveredMonomerFromEditorMol} from './get-hovered';
15
14
  import {_getHelmService} from '../package-utils';
16
15
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
@@ -143,7 +142,8 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
143
142
  this.logger.warning(`${logPrefix}, editorMol of the cell not found.`);
144
143
  return; // The gridCell is not rendered yet
145
144
  }
146
- const seqMonomer: ISeqMonomer | null = getHoveredMonomerFromEditorMol(argsX, argsY, gridCell, editorMol);
145
+ const seqMonomer: ISeqMonomer | null =
146
+ getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
147
147
 
148
148
  if (seqMonomer) {
149
149
  const monomerLib = getMonomerLib();