@datagrok/sequence-translator 1.1.5 → 1.2.0
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 +6 -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/img/icons/calculator.png +0 -0
- package/img/icons/pattern.png +0 -0
- package/img/icons/structure.png +0 -0
- package/img/icons/toolkit.png +0 -0
- package/img/icons/translator.png +0 -0
- package/package.json +1 -1
- package/src/demo/demo-st-ui.ts +26 -36
- package/src/model/helpers.ts +17 -0
- package/src/model/sequence-to-structure-utils/monomer-code-parser.ts +2 -5
- package/src/model/sequence-to-structure-utils/sdf-tab.ts +1 -1
- package/src/model/sequence-to-structure-utils/sequence-to-molfile.ts +20 -3
- package/src/package.ts +57 -37
- package/src/plugins/const.ts +4 -0
- package/src/plugins/mermade.ts +48 -0
- package/src/view/app-ui.ts +193 -0
- package/src/view/{tabs/axolabs.ts → apps/oligo-pattern.ts} +106 -26
- package/src/view/{tabs/sdf.ts → apps/oligo-structure.ts} +13 -14
- package/src/view/{tabs/main.ts → apps/oligo-translator.ts} +15 -11
- package/src/view/const/ui.ts +14 -0
- package/src/view/style/pattern-app.css +1 -0
- package/src/view/style/structure-app.css +39 -0
- package/src/view/style/translator-app.css +46 -0
- package/src/view/utils/colored-input/colored-text-input.ts +7 -6
- package/src/view/utils/molecule-img.ts +21 -10
- package/src/view/utils/router.ts +71 -0
- package/src/demo/handle-error.ts +0 -12
- package/src/view/const/view.ts +0 -10
- package/src/view/css/axolabs-tab.css +0 -1
- package/src/view/css/main-tab.css +0 -46
- package/src/view/css/sdf-tab.css +0 -39
- package/src/view/view.ts +0 -127
- /package/src/view/const/{main-tab.ts → oligo-translator.ts} +0 -0
- /package/src/view/{css → style}/colored-text-input.css +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
import * as DG from 'datagrok-api/dg';
|
|
5
|
+
|
|
6
|
+
class MultiviewRouter {
|
|
7
|
+
constructor(private view: DG.View) {
|
|
8
|
+
this.pathParts = window.location.pathname.split('/');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
private appName: string;
|
|
12
|
+
private tabName: string;
|
|
13
|
+
private searchParams: URLSearchParams;
|
|
14
|
+
private pathParts: string[];
|
|
15
|
+
|
|
16
|
+
navigate() {
|
|
17
|
+
this.parseUrl();
|
|
18
|
+
this.updateHistory();
|
|
19
|
+
this.updateView();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
parseUrl() {
|
|
23
|
+
this.appName = this.pathParts[1];
|
|
24
|
+
this.tabName = this.pathParts[2];
|
|
25
|
+
this.searchParams = new URLSearchParams(window.location.search);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private getUrl() {
|
|
29
|
+
return '/' + this.appName + '/' + this.tabName + '?' + this.searchParams.toString();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
updateHistory() {
|
|
33
|
+
window.history.pushState({}, '', this.getUrl());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
updateView() {
|
|
37
|
+
this.view.path = this.getUrl();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// class Router {
|
|
42
|
+
// constructor(private readonly view: DG.View) {
|
|
43
|
+
// this.pathParts = window.location.pathname.split('/');
|
|
44
|
+
// console.log(`pathParts:`, this.pathParts);
|
|
45
|
+
// this.searchParams = new URLSearchParams(window.location.search);
|
|
46
|
+
// console.log(`searchParams:`, this.searchParams);
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
// searchParams: URLSearchParams;
|
|
50
|
+
// private pathParts: string[];
|
|
51
|
+
|
|
52
|
+
// getUrlParamsString(): string {
|
|
53
|
+
// return Object.entries(this.searchParams)
|
|
54
|
+
// .map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
|
|
55
|
+
// }
|
|
56
|
+
|
|
57
|
+
// updatePath(control: DG.TabControl) {
|
|
58
|
+
// const urlParamsTxt: string = Object.entries(this.searchParams)
|
|
59
|
+
// .map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
|
|
60
|
+
// this.view.path = '/apps/SequenceTranslator' + `/${control.currentPane.name}`;
|
|
61
|
+
// if (urlParamsTxt)
|
|
62
|
+
// this.view.path += `/?${urlParamsTxt}`;
|
|
63
|
+
// }
|
|
64
|
+
|
|
65
|
+
// get tabName(): string {
|
|
66
|
+
// const idx = this.pathParts.findIndex((el) => el === 'SequenceTranslator');
|
|
67
|
+
// if (idx === -1) // todo: remove after verification of validity condition
|
|
68
|
+
// return '';
|
|
69
|
+
// return this.pathParts[idx + 1];
|
|
70
|
+
// }
|
|
71
|
+
// }
|
package/src/demo/handle-error.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as grok from 'datagrok-api/grok';
|
|
2
|
-
import * as DG from 'datagrok-api/dg';
|
|
3
|
-
import * as ui from 'datagrok-api/ui';
|
|
4
|
-
|
|
5
|
-
import {_package} from '../package';
|
|
6
|
-
|
|
7
|
-
export function handleError(err: any): void {
|
|
8
|
-
const errMsg: string = err instanceof Error ? err.message : err.toString();
|
|
9
|
-
const stack: string | undefined = err instanceof Error ? err.stack : undefined;
|
|
10
|
-
grok.shell.error(errMsg);
|
|
11
|
-
_package.logger.error(err.message, undefined, stack);
|
|
12
|
-
}
|
package/src/view/const/view.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
-
import * as grok from 'datagrok-api/grok';
|
|
3
|
-
import * as ui from 'datagrok-api/ui';
|
|
4
|
-
import * as DG from 'datagrok-api/dg';
|
|
5
|
-
|
|
6
|
-
export const MAIN_TAB = 'SEQUENCE';
|
|
7
|
-
export const AXOLABS_TAB = 'PATTERN';
|
|
8
|
-
export const SDF_TAB = 'SDF';
|
|
9
|
-
|
|
10
|
-
export const DEFAULT_AXOLABS_INPUT = 'Afcgacsu';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/* Naming convention: class names should begin with st and tab name (main, axo, sdf) to avoid naming collitions */
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/* Naming convention: class names should begin with st and tab name (main, axo, sdf) to avoid naming collitions */
|
|
2
|
-
.st-main-input-table {
|
|
3
|
-
width: 100%;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.st-main-input-table td:has(textarea) {
|
|
7
|
-
width: 100%;
|
|
8
|
-
padding-right: 20px;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.st-main-input-table td:has(select) {
|
|
12
|
-
min-width: 120px;
|
|
13
|
-
vertical-align: top;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.st-main-output-table {
|
|
17
|
-
margin-top: 20px;
|
|
18
|
-
margin-right: 20px;
|
|
19
|
-
margin-bottom: 10px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.st-main-output-table table {
|
|
23
|
-
width: 100%;
|
|
24
|
-
table-layout: fixed;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/* .st-main-output-table table tbody tr td { */
|
|
28
|
-
/* max-width: 20%; */
|
|
29
|
-
/* } */
|
|
30
|
-
|
|
31
|
-
.st-main-output-table td {
|
|
32
|
-
padding-top: 6px;
|
|
33
|
-
padding-bottom: 6px;
|
|
34
|
-
}
|
|
35
|
-
.st-main-output-table tr:nth-child(even) {
|
|
36
|
-
background-color: var(--grey-1);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.st-main-output-table td:nth-child(odd) {
|
|
40
|
-
width: 120px;
|
|
41
|
-
vertical-align: top;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.st-main-output-table td a {
|
|
45
|
-
overflow-wrap: break-word;
|
|
46
|
-
}
|
package/src/view/css/sdf-tab.css
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/* Naming convention: class names should begin with st and tab name (main, axo, sdf) to avoid naming collitions */
|
|
2
|
-
|
|
3
|
-
.st-sdf-body {
|
|
4
|
-
padding-right: 20px;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.st-sdf-input-form {
|
|
8
|
-
text-align: right;
|
|
9
|
-
vertical-align: top;
|
|
10
|
-
min-width: 95px;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.st-sdf-direction-choice label {
|
|
14
|
-
min-width: 100px;
|
|
15
|
-
float: right;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.st-sdf-direction-choice div {
|
|
19
|
-
justify-content: right;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.st-sdf-text-input-td { /* Style for td containing textarea */
|
|
23
|
-
width: 100%;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.st-sdf-mol-img {
|
|
27
|
-
margin-right: 30px;
|
|
28
|
-
float: right;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.st-sdf-bool-button-block {
|
|
32
|
-
justify-content: right;
|
|
33
|
-
margin-bottom: 10px;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.st-sdf-bottom {
|
|
37
|
-
flex-direction: row-reverse;
|
|
38
|
-
padding-top: 20px;
|
|
39
|
-
}
|
package/src/view/view.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
-
import * as grok from 'datagrok-api/grok';
|
|
3
|
-
import * as ui from 'datagrok-api/ui';
|
|
4
|
-
import * as DG from 'datagrok-api/dg';
|
|
5
|
-
|
|
6
|
-
import {MAIN_TAB, AXOLABS_TAB, SDF_TAB} from './const/view';
|
|
7
|
-
import {MainTabUI} from './tabs/main';
|
|
8
|
-
import {SdfTabUI} from './tabs/sdf';
|
|
9
|
-
import {AxolabsTabUI} from './tabs/axolabs';
|
|
10
|
-
import {MonomerLibViewer} from './monomer-lib-viewer/viewer';
|
|
11
|
-
|
|
12
|
-
export class SequenceTranslatorUI {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.view = DG.View.create();
|
|
15
|
-
this.urlRouter = new URLRouter(this.view);
|
|
16
|
-
this.view.box = true;
|
|
17
|
-
this.view.name = 'Sequence Translator';
|
|
18
|
-
|
|
19
|
-
const windows = grok.shell.windows;
|
|
20
|
-
windows.showProperties = false;
|
|
21
|
-
windows.showToolbox = false;
|
|
22
|
-
windows.showHelp = false;
|
|
23
|
-
|
|
24
|
-
const viewMonomerLibIcon = ui.iconFA('book', MonomerLibViewer.view, 'View monomer library');
|
|
25
|
-
this.topPanel = [
|
|
26
|
-
viewMonomerLibIcon,
|
|
27
|
-
];
|
|
28
|
-
this.view.setRibbonPanels([this.topPanel]);
|
|
29
|
-
|
|
30
|
-
this.tabs = new TabLayout(
|
|
31
|
-
new MainTabUI(),
|
|
32
|
-
new AxolabsTabUI(),
|
|
33
|
-
new SdfTabUI(),
|
|
34
|
-
this.urlRouter
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private readonly view: DG.View;
|
|
39
|
-
public readonly tabs: TabLayout;
|
|
40
|
-
private readonly topPanel: HTMLElement[];
|
|
41
|
-
private readonly urlRouter: URLRouter;
|
|
42
|
-
|
|
43
|
-
/** Create master layout of the app */
|
|
44
|
-
public async createLayout(): Promise<void> {
|
|
45
|
-
const tabControl = await this.tabs.getControl();
|
|
46
|
-
|
|
47
|
-
const tabName = this.urlRouter.tabName;
|
|
48
|
-
if (tabName)
|
|
49
|
-
tabControl.currentPane = tabControl.getPane(tabName);
|
|
50
|
-
this.view.append(tabControl);
|
|
51
|
-
|
|
52
|
-
grok.shell.addView(this.view);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
class TabLayout {
|
|
57
|
-
constructor(
|
|
58
|
-
public readonly mainTab: MainTabUI,
|
|
59
|
-
public readonly axolabsTab: AxolabsTabUI,
|
|
60
|
-
public readonly sdfTab: SdfTabUI,
|
|
61
|
-
private readonly urlRouter: URLRouter
|
|
62
|
-
) {}
|
|
63
|
-
|
|
64
|
-
private control: DG.TabControl | null = null;
|
|
65
|
-
|
|
66
|
-
async getControl(): Promise<DG.TabControl> {
|
|
67
|
-
if (this.control)
|
|
68
|
-
return this.control;
|
|
69
|
-
const control = ui.tabControl({
|
|
70
|
-
[MAIN_TAB]: await this.mainTab.getHtmlElement(),
|
|
71
|
-
[AXOLABS_TAB]: this.axolabsTab.htmlDivElement,
|
|
72
|
-
[SDF_TAB]: await this.sdfTab.getHtmlDivElement(),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const sdfPane = control.getPane(SDF_TAB);
|
|
76
|
-
ui.tooltip.bind(sdfPane.header, 'Get atomic-level structure for SS + AS/AS2 and save SDF');
|
|
77
|
-
|
|
78
|
-
const mainPane = control.getPane(MAIN_TAB);
|
|
79
|
-
ui.tooltip.bind(mainPane.header, 'Translate across formats');
|
|
80
|
-
|
|
81
|
-
const axolabsPane = control.getPane(AXOLABS_TAB);
|
|
82
|
-
ui.tooltip.bind(axolabsPane.header, 'Create modification pattern for SS and AS');
|
|
83
|
-
|
|
84
|
-
control.onTabChanged.subscribe(() => {
|
|
85
|
-
if (control.currentPane.name !== MAIN_TAB)
|
|
86
|
-
this.urlRouter.searchParams.delete('seq');
|
|
87
|
-
else {
|
|
88
|
-
this.urlRouter.searchParams.set('seq', this.mainTab.sequence);
|
|
89
|
-
}
|
|
90
|
-
this.urlRouter.updatePath(control);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.control = control;
|
|
94
|
-
|
|
95
|
-
return this.control;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
class URLRouter {
|
|
100
|
-
constructor(private readonly view: DG.View) {
|
|
101
|
-
this.pathParts = window.location.pathname.split('/');
|
|
102
|
-
this.searchParams = new URLSearchParams(window.location.search);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public searchParams: URLSearchParams;
|
|
106
|
-
private pathParts: string[];
|
|
107
|
-
|
|
108
|
-
get urlParamsString(): string {
|
|
109
|
-
return Object.entries(this.searchParams)
|
|
110
|
-
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public updatePath(control: DG.TabControl) {
|
|
114
|
-
const urlParamsTxt: string = Object.entries(this.searchParams)
|
|
115
|
-
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
|
|
116
|
-
this.view.path = '/apps/SequenceTranslator' + `/${control.currentPane.name}`;
|
|
117
|
-
if (urlParamsTxt)
|
|
118
|
-
this.view.path += `/?${urlParamsTxt}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
get tabName(): string {
|
|
122
|
-
const idx = this.pathParts.findIndex((el) => el === 'SequenceTranslator');
|
|
123
|
-
if (idx === -1) // todo: remove after verification of validity condition
|
|
124
|
-
return '';
|
|
125
|
-
return this.pathParts[idx + 1];
|
|
126
|
-
}
|
|
127
|
-
}
|
|
File without changes
|
|
File without changes
|