Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6055 – Allow multiple library updates and updating in micro-mode #6058

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Parameters:
* `backgroundColor` – image background color
* `bondThickness` – thickness of bonds in output structure

`updateMonomersLibrary(monomersData: string | JSON): void` – given the monomers data, perform upsert operation for the built-in monomers library in the macromolecules editor. Might be invoked only when macromolecules editor is turned on. Update (replace) operation is performed for the particular monomer if its alias and class are matching with the existing one. Otherwise, insert operation is performed.
`updateMonomersLibrary(monomersData: string | JSON): void` – given the monomers data, perform upsert operation for the built-in monomers library in the macromolecules editor. Update (replace) operation is performed for the particular monomer if its alias and class are matching with the existing one. Otherwise, insert operation is performed.
Parameters: `monomersData: string | JSON` – monomers description in KET format being formatted as either JSON notation or this JSON being stringified to be more concise.

## Settings
Expand Down
56 changes: 33 additions & 23 deletions packages/ketcher-core/src/application/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ interface ICoreEditorConstructorParams {
theme;
canvas: SVGSVGElement;
mode?: BaseMode;
// Raw monomers data in KET format that has to be applied as library update ahead of time on Ketcher initialization – check `updateMonomersLibrary` method of Ketcher API
monomersLibraryUpdate?: string | JSON;
}

Expand All @@ -71,6 +72,7 @@ function isMouseMainButtonPressed(event: MouseEvent) {
let persistentMonomersLibrary: MonomerItemType[] = [];
let persistentMonomersLibraryParsedJson: IKetMacromoleculesContent | null =
null;
let storedMonomersLibraryUpdates: Array<string | JSON> = [];

let editor;
export class CoreEditor {
Expand Down Expand Up @@ -118,11 +120,7 @@ export class CoreEditor {
this.mode = mode ?? new SequenceMode();
resetEditorEvents();
this.events = editorEvents;
this.setMonomersLibrary(monomersDataRaw);
this._monomersLibraryParsedJson = JSON.parse(monomersDataRaw);
if (monomersLibraryUpdate) {
this.updateMonomersLibrary(monomersLibraryUpdate);
}
this.setMonomersLibrary(monomersDataRaw, monomersLibraryUpdate);
this.subscribeEvents();
this.renderersContainer = new RenderersManager({ theme });
this.drawingEntitiesManager = new DrawingEntitiesManager();
Expand Down Expand Up @@ -158,7 +156,10 @@ export class CoreEditor {
return { monomersLibraryParsedJson, monomersLibrary };
}

private setMonomersLibrary(monomersDataRaw: string) {
private setMonomersLibrary(
monomersDataRaw: string,
initialMonomersLibraryUpdate?: string | JSON,
) {
if (
persistentMonomersLibrary.length !== 0 &&
persistentMonomersLibraryParsedJson !== undefined
Expand All @@ -172,8 +173,21 @@ export class CoreEditor {
this.parseMonomersLibrary(monomersDataRaw);
this._monomersLibrary = monomersLibrary;
this._monomersLibraryParsedJson = monomersLibraryParsedJson;
persistentMonomersLibrary = monomersLibrary;
persistentMonomersLibraryParsedJson = monomersLibraryParsedJson;

if (initialMonomersLibraryUpdate) {
this.updateMonomersLibrary(initialMonomersLibraryUpdate);
}
storedMonomersLibraryUpdates.forEach((storedMonomersLibraryUpdate) => {
this.updateMonomersLibrary(storedMonomersLibraryUpdate);
});
storedMonomersLibraryUpdates = [];

persistentMonomersLibrary = this._monomersLibrary;
persistentMonomersLibraryParsedJson = this._monomersLibraryParsedJson;
}

static storeMonomersLibraryUpdate(monomersDataRaw: string | JSON) {
storedMonomersLibraryUpdates.push(monomersDataRaw);
}

public updateMonomersLibrary(monomersDataRaw: string | JSON) {
Expand All @@ -183,6 +197,10 @@ export class CoreEditor {
} = this.parseMonomersLibrary(monomersDataRaw);

newMonomersLibraryChunk.forEach((newMonomer) => {
if (!this._monomersLibraryParsedJson) {
return;
}

const existingMonomerIndex = this._monomersLibrary.findIndex(
(monomer) => {
return (
Expand All @@ -202,35 +220,27 @@ export class CoreEditor {
this._monomersLibrary[existingMonomerIndex].props;
const existingMonomerIdToUse =
existingMonomerProps.id || existingMonomerProps.MonomerName;
// It's safe to use non-null assertion here and below because we already specified monomers library and parsed JSON before
const existingMonomerRefIndex =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._monomersLibraryParsedJson!.root.templates.findIndex(
this._monomersLibraryParsedJson.root.templates.findIndex(
(template) => template.$ref === existingMonomerIdToUse,
);
if (existingMonomerRefIndex && existingMonomerRefIndex !== -1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
delete this._monomersLibraryParsedJson!.root.templates[
delete this._monomersLibraryParsedJson.root.templates[
existingMonomerRefIndex
];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
delete this._monomersLibraryParsedJson![existingMonomerIdToUse];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._monomersLibraryParsedJson!.root.templates.push({
delete this._monomersLibraryParsedJson[existingMonomerIdToUse];
this._monomersLibraryParsedJson.root.templates.push({
$ref: monomerIdToUse,
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._monomersLibraryParsedJson![monomerIdToUse] =
this._monomersLibraryParsedJson[monomerIdToUse] =
newMonomersLibraryChunkParsedJson[monomerIdToUse];
}
} else {
this._monomersLibrary.push(newMonomer);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._monomersLibraryParsedJson!.root.templates.push({
this._monomersLibraryParsedJson.root.templates.push({
$ref: monomerIdToUse,
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this._monomersLibraryParsedJson![monomerIdToUse] =
this._monomersLibraryParsedJson[monomerIdToUse] =
newMonomersLibraryChunkParsedJson[monomerIdToUse];
}
});
Expand Down
11 changes: 3 additions & 8 deletions packages/ketcher-core/src/application/ketcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import {
import {
deleteAllEntitiesOnCanvas,
getStructure,
ketcherProvider,
parseAndAddMacromoleculesOnCanvas,
prepareStructToRender,
} from './utils';
Expand Down Expand Up @@ -542,14 +541,10 @@ export class Ketcher {
public updateMonomersLibrary(rawMonomersData: string | JSON) {
const editor = CoreEditor.provideEditorInstance();

ketcherProvider.getKetcher();

if (!editor) {
throw new Error(
'Updating monomer library in small molecules mode is not allowed, please switch to macromolecules mode',
);
CoreEditor.storeMonomersLibraryUpdate(rawMonomersData);
} else {
editor.updateMonomersLibrary(rawMonomersData);
}

editor.updateMonomersLibrary(rawMonomersData);
}
}
Loading