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

#3129 - Full template preview following mouse cursor #3252

Merged
merged 12 commits into from
Sep 26, 2023
Merged
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import {
clickInTheMiddleOfTheScreen,
takeEditorScreenshot,
STRUCTURE_LIBRARY_BUTTON_NAME,
waitForPageInit,
} from '@utils';

test.describe('Open Ketcher', () => {
test.describe('Salts and Solvents replacement', () => {
test.beforeEach(async ({ page }) => {
await page.goto('');
await waitForPageInit(page);
});

test.afterEach(async ({ page }) => {
await takeEditorScreenshot(page);
});

test('Verify if the new Salt or Solvent is replacing old one', async ({
Expand All @@ -31,7 +36,6 @@ Test case: EPMLSOPKET-12972 - 'Check that new Salt or Solvent is replacing the p
await page.getByRole('tab', { name: 'Salts and Solvents' }).click();
await selectSaltsAndSolvents(SaltsAndSolvents.AceticAcid, page);
await clickInTheMiddleOfTheScreen(page);
await takeEditorScreenshot(page);
});

test('Verify if Methan Sulphonic Acid replace the Nitrogen atom', async ({
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable no-magic-numbers */
import { test, Page } from '@playwright/test';
import { test, Page, expect } from '@playwright/test';
import { BondType } from '@utils/canvas/types';
import { getAtomByIndex } from '@utils/canvas/atoms';
import { selectButtonByTitle } from '@utils/clicks/selectButtonByTitle';
Expand All @@ -20,9 +20,9 @@ import {
waitForPageInit,
} from '@utils';

async function createToolTipScreenshot(type: RingButton, page: Page) {
await page.getByRole('button', { name: type }).hover();
await takeEditorScreenshot(page);
async function checkTooltip(type: RingButton, page: Page) {
const templateButton = page.getByRole('button', { name: type });
await expect(templateButton).toHaveAttribute('title', `${type} (T)`);
}

async function placeTwoRingsMergedByAtom(type: RingButton, page: Page) {
Expand Down Expand Up @@ -78,9 +78,8 @@ async function checkHistoryForBondDeletion(page: Page) {
await selectTopPanelButton(TopPanelButton.Undo, page);
}

async function ManipulateRingsByName(type: RingButton, page: Page) {
// checking the tooltip
await createToolTipScreenshot(type, page);
async function manipulateRingsByName(type: RingButton, page: Page) {
await checkTooltip(type, page);
await placeTwoRingsMergedByAtom(type, page);
await takeEditorScreenshot(page);
await selectTopPanelButton(TopPanelButton.Clear, page);
Expand Down Expand Up @@ -110,43 +109,13 @@ test.describe('Templates - Rings manipulations', () => {
await takeEditorScreenshot(page);
});

test('Benzene', async ({ page }) => {
// EPLMSOCKET-1668
await ManipulateRingsByName(RingButton.Benzene, page);
});

test('Cyclopentadiene', async ({ page }) => {
// EPLMSOCKET-1675
await ManipulateRingsByName(RingButton.Cyclopentane, page);
});

test('Cyclohexane', async ({ page }) => {
// EPLMSOCKET-1677
await ManipulateRingsByName(RingButton.Cyclohexane, page);
});

test('Cyclopentane', async ({ page }) => {
// EPLMSOCKET-1679
await ManipulateRingsByName(RingButton.Cyclopentane, page);
});
const templates = Object.values(RingButton);

test('Cyclopropane', async ({ page }) => {
// EPLMSOCKET-1680
await ManipulateRingsByName(RingButton.Cyclopropane, page);
});

test('Cyclobutane', async ({ page }) => {
// EPLMSOCKET-1681
await ManipulateRingsByName(RingButton.Cyclobutane, page);
});

test('Cycloheptane', async ({ page }) => {
// EPLMSOCKET-1682
await ManipulateRingsByName(RingButton.Cycloheptane, page);
});

test('Cyclooctane', async ({ page }) => {
// EPLMSOCKET-1683
await ManipulateRingsByName(RingButton.Benzene, page);
});
for (const template of templates) {
test(template, async ({ page }) => {
// EPLMSOPCKET-1668, EPLMSOPCKET-1675, EPLMSOPCKET-1677, EPLMSOPCKET-1679, EPLMSOPCKET-1680, EPLMSOPCKET-1681
// EPLMSOPCKET-1682, EPLMSOPCKET-1683
await manipulateRingsByName(template, page);
});
}
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,41 @@ test.describe('Preview for abbreviated structures: functional groups', () => {
await delay(DELAY_IN_SECONDS.ONE);
await takeEditorScreenshot(page);
});

test('Should show a preview following the mouse cursor', async ({ page }) => {
const bondId = 2;
const shift = 100;
await selectRingButton(RingButton.Benzene, page);
const bondPosition = await getBondByIndex(
page,
{ type: BondType.SINGLE },
bondId,
);
const pointAwayFromBond = {
x: bondPosition.x + shift,
y: bondPosition.y + shift,
};
await page.mouse.move(pointAwayFromBond.x, pointAwayFromBond.y);
await takeEditorScreenshot(page);
});

test('Should show a preview following the mouse cursor and hide it when a bond is hovered over', async ({
page,
}) => {
const bondId = 2;
const shift = 100;
await selectRingButton(RingButton.Benzene, page);
const bondPosition = await getBondByIndex(
page,
{ type: BondType.SINGLE },
bondId,
);
const pointAwayFromBond = {
x: bondPosition.x + shift,
y: bondPosition.y + shift,
};
await takeEditorScreenshot(page);
await page.mouse.move(pointAwayFromBond.x, pointAwayFromBond.y);
await takeEditorScreenshot(page);
Comment on lines +120 to +134
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this test covers the case from the previous one and we can keep just only this test.

});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
$RXN

-INDIGO- 0918230300
-INDIGO- 0925231455

1 1
$MOL

-INDIGO-09182303002D
-INDIGO-09252314552D

11 10 0 0 0 0 0 0 0 0999 V2000
10.7449 -8.0500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
Expand All @@ -32,7 +32,7 @@ $MOL
M END
$MOL

-INDIGO-09182303002D
-INDIGO-09252314552D

6 6 0 0 0 0 0 0 0 0999 V2000
17.9598 -11.5501 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
Expand Down
5 changes: 5 additions & 0 deletions packages/ketcher-core/src/application/editor/actions/paste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
TextCreate,
CalcImplicitH,
FragmentSetProperties,
BondAttr,
AtomAttr,
} from '../operations';
import { fromRGroupAttrs, fromUpdateIfThen } from './rgroup';

Expand All @@ -39,6 +41,7 @@ export function fromPaste(
pstruct,
point,
angle = 0,
isPreview = false,
): [Action, { atoms: number[]; bonds: number[] }] {
const xy0 = getStructCenter(pstruct);
const offset = Vec2.diff(point, xy0);
Expand Down Expand Up @@ -114,10 +117,12 @@ export function fromPaste(
action.addOp(operation);

pasteItems.bonds.push(operation.data.bid);
new BondAttr(operation.data.bid, 'isPreview', isPreview).perform(restruct);
});

pasteItems.atoms.forEach((aid) => {
action.addOp(new CalcImplicitH([aid]).perform(restruct));
new AtomAttr(aid, 'isPreview', isPreview).perform(restruct);
});

pstruct.sgroups.forEach((sg: SGroup) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ export function fromTemplateOnCanvas(
restruct,
template,
pos,
angle,
angle = 0,
): [Action, { atoms: number[]; bonds: number[] }] {
const [action, pasteItems] = fromPaste(
restruct,
template.molecule,
pos,
angle,
true,
);

action.addOp(new CalcImplicitH(pasteItems.atoms).perform(restruct));
Expand Down
10 changes: 8 additions & 2 deletions packages/ketcher-react/src/script/editor/shared/closest.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ function findClosestAtom(restruct, pos, skip, minDist) {
) {
return null;
}
if (aid === skipId) return;
const isSkippedAtom = aid === skipId || atom.a.isPreview;
if (isSkippedAtom) {
return;
}

const dist = Vec2.dist(pos, atom.a.pp);

Expand Down Expand Up @@ -182,7 +185,10 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
let minCDist = minDist;

restruct.bonds.forEach((bond, bid) => {
if (bid === skipId) return;
const isSkippedBond = bid === skipId || bond.b.isPreview;
if (isSkippedBond) {
return;
}

const p1 = restruct.atoms.get(bond.b.begin).a.pp;
const p2 = restruct.atoms.get(bond.b.end).a.pp;
Expand Down
28 changes: 17 additions & 11 deletions packages/ketcher-react/src/script/editor/tool/paste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,18 @@ class PasteTool implements Tool {
this.action = action;
this.editor.update(this.action, true);

action.mergeWith(
expandSGroupWithMultipleAttachmentPoint(this.editor.render.ctab),
);
action.mergeWith(expandSGroupWithMultipleAttachmentPoint(this.restruct));

this.editor.update(this.action, true);

this.mergeItems = getItemsToFuse(this.editor, pasteItems);
this.editor.hover(getHoverToFuse(this.mergeItems), this);
}

private get restruct() {
return this.editor.render.ctab;
}

mousedown(event) {
if (
!this.isSingleContractedGroup ||
Expand All @@ -81,7 +83,7 @@ class PasteTool implements Tool {

if (this.action) {
// remove pasted group from canvas to find closest group correctly
this.action?.perform(this.editor.render.ctab);
this.action?.perform(this.restruct);
}

const closestGroupItem = this.editor.findItem(event, ['functionalGroups']);
Expand All @@ -91,7 +93,7 @@ class PasteTool implements Tool {
if (!closestGroupItem || SGroup.isSaltOrSolvent(closestGroup?.data.name)) {
// recreate action and continue as usual
const [action] = fromPaste(
this.editor.render.ctab,
this.restruct,
this.struct,
this.editor.render.page2obj(event),
);
Expand All @@ -110,7 +112,7 @@ class PasteTool implements Tool {

mousemove(event) {
if (this.action) {
this.action?.perform(this.editor.render.ctab);
this.action?.perform(this.restruct);
}

if (this.dragCtx) {
Expand Down Expand Up @@ -149,13 +151,13 @@ class PasteTool implements Tool {
return;

if (this.dragCtx.action) {
this.dragCtx.action.perform(this.editor.render.ctab);
this.dragCtx.action.perform(this.restruct);
}

this.dragCtx.angle = degrees;

const [action] = fromTemplateOnAtom(
this.editor.render.ctab,
this.restruct,
prepareTemplateFromSingleGroup(this.struct),
atomId,
angle,
Expand All @@ -174,7 +176,7 @@ class PasteTool implements Tool {
});
// common paste logic
const [action, pasteItems] = fromPaste(
this.editor.render.ctab,
this.restruct,
this.struct,
this.editor.render.page2obj(event),
);
Expand Down Expand Up @@ -215,10 +217,10 @@ class PasteTool implements Tool {
delete this.dragCtx;

dragCtx.action = dragCtx.action
? fromItemsFuse(this.editor.render.ctab, dragCtx.mergeItems).mergeWith(
? fromItemsFuse(this.restruct, dragCtx.mergeItems).mergeWith(
dragCtx.action,
)
: fromItemsFuse(this.editor.render.ctab, dragCtx.mergeItems);
: fromItemsFuse(this.restruct, dragCtx.mergeItems);

this.editor.hover(null);
this.editor.update(dragCtx.action);
Expand Down Expand Up @@ -247,6 +249,10 @@ class PasteTool implements Tool {
mouseleave() {
this.cancel();
}

mouseLeaveClientArea() {
this.cancel();
}
}

type Template = {
Expand Down
Loading