Skip to content

Commit

Permalink
Macro: #3495 - Is not possible to add RNA presets into the Favourite …
Browse files Browse the repository at this point in the history
…library (#3584)

* #3495 add RNA presets into the Favourite library

* #3495 fix ci error

* #3495 update tests

* #3495 fix input lost focus issue

* #3495 disable duplication for undefined preset

* #3495 fix dispatch selectTool rerender issue

* #3495 fix preset name auto fill issue

* #3495 fix screenshots

* #3495 fix ci issue

* #3495 fix autotest issue and prevent rerender of RnaEditor

* #3495 fix ci issue

* #3495 fix unit tests

* #3495 update screenshots

* #3495 fix duplicate preset name issue

* #3495 fix duplicated preset name issue

* #3495 fix autotests

* #3495 update screenshot

* #3495 merge choosing RNA parts

* #3495 refresh selected monomer after changed monomer group

* #3495 enable expanding monomer group not in edit mode
  • Loading branch information
StarlaStarla authored Dec 1, 2023
1 parent cfb891b commit ceb5a86
Show file tree
Hide file tree
Showing 46 changed files with 949 additions and 389 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test, expect } from '@playwright/test';
import { waitForPageInit } from '@utils/common';
import { takePageScreenshot } from '@utils';
import { gotoRNA } from '@utils/macromolecules/rnaBuilder';

test.describe('Macromolecules add RNA presets to Favorites', () => {
test.beforeEach(async ({ page }) => {
await waitForPageInit(page);
await gotoRNA(page);
});

test('Should have star when hover over RNA presets', async ({ page }) => {
await page.getByTestId('A_A_R_P').hover();
await takePageScreenshot(page);
});

test('Should add RNA presets to Favorites', async ({ page }) => {
await page.getByTestId('FAVORITES-TAB').click();
await expect(page.getByTestId('A_A_R_P')).not.toBeVisible();

await page.getByTestId('RNA-TAB').click();
await page.locator('div[class="star "]').first().click();
await page.getByTestId('FAVORITES-TAB').click();
await expect(page.getByTestId('A_A_R_P')).toBeVisible();
});
});
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,15 +1,7 @@
import { Page, test, expect } from '@playwright/test';
import { RNA_TAB } from '@constants/testIdConstants';
import { test, expect } from '@playwright/test';
import { waitForPageInit } from '@utils/common';
import { takePageScreenshot } from '@utils';
import { turnOnMacromoleculesEditor } from '@utils/macromolecules';
import { toggleRnaBuilderAccordion } from '@utils/macromolecules/rnaBuilder';

async function gotoRNA(page: Page) {
await turnOnMacromoleculesEditor(page);
await page.getByTestId(RNA_TAB).click();
await toggleRnaBuilderAccordion(page);
}
import { gotoRNA } from '@utils/macromolecules/rnaBuilder';

test.describe('Macromolecules delete RNA presets', () => {
test.beforeEach(async ({ page }) => {
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.
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.
8 changes: 8 additions & 0 deletions ketcher-autotests/tests/utils/macromolecules/rnaBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Page } from '@playwright/test';
import { turnOnMacromoleculesEditor } from '.';
import { RNA_TAB } from '@constants/testIdConstants';

export async function toggleRnaBuilderAccordion(page: Page) {
await page.getByText('RNA Builder').locator('button').click();
}

export async function gotoRNA(page: Page) {
await turnOnMacromoleculesEditor(page);
await page.getByTestId(RNA_TAB).click();
await toggleRnaBuilderAccordion(page);
}
6 changes: 5 additions & 1 deletion packages/ketcher-core/src/application/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ export class CoreEditor {
}

private onSelectRNAPreset(preset: IRnaPreset) {
this.selectTool('preset', preset);
if (preset) {
this.selectTool('preset', preset);
} else {
this.tool = undefined;
}
}

private onSelectTool(tool: string) {
Expand Down
4 changes: 2 additions & 2 deletions packages/ketcher-polymer-editor-react/src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ function Editor({ theme, togglerComponent }: EditorProps) {
debouncedShowPreview({ monomer, style: previewStyle });
}, []);

const handleClosePreview = () => {
const handleClosePreview = useCallback(() => {
debouncedShowPreview.cancel();
dispatch(showPreview(undefined));
};
}, []);

useEffect(() => {
editor?.events.mouseOverMonomer.add((e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import React from 'react';
import styled from '@emotion/styled';
import { MONOMER_LIBRARY_WIDTH } from 'components/monomerLibrary';
import { MONOMER_LIBRARY_WIDTH } from 'components/monomerLibrary/styles';

interface LayoutProps {
children: JSX.Element | Array<JSX.Element>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,16 @@ const monomerData = [
},
];
describe('RNA ContextMenu', () => {
const editPreset = jest.fn();
const duplicatePreset = jest.fn();
it('should render contextMenu correctly', () => {
render(
withThemeAndStoreProvider(
<RnaBuilder libraryName={MONOMER_TYPES.RNA} />,
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>,
{
library: {
searchFilter: '',
Expand All @@ -84,7 +90,11 @@ describe('RNA ContextMenu', () => {
it("should disable 'Delete Preset' menu when trying to delete default preset", () => {
render(
withThemeAndStoreProvider(
<RnaBuilder libraryName={MONOMER_TYPES.RNA} />,
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>,
{
library: {
searchFilter: '',
Expand All @@ -104,7 +114,11 @@ describe('RNA ContextMenu', () => {
render(
withThemeAndStoreProvider(
<div>
<RnaBuilder libraryName={MONOMER_TYPES.RNA} />
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>
<ModalContainer />
</div>,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { openModal } from 'state/modal';
import { useAppDispatch, useAppSelector } from 'hooks';
import { ReactElement } from 'react';
import { CONTEXT_MENU_ID } from './types';
import { selectCurrentTabIndex, setSelectedTabIndex } from 'state/library';
import { selectActivePresetForContextMenu } from 'state/rna-builder';
import { StyledMenu } from './styles';

export const RNAContextMenu = () => {
const RNA_TAB_INDEX = 2;
const dispatch = useAppDispatch();
const activePresetForContextMenu = useAppSelector(
selectActivePresetForContextMenu,
);
const selectedTabIndex = useAppSelector(selectCurrentTabIndex);
const RNAMenus = [
{ name: 'duplicateandedit', title: 'Duplicate and Edit...' },
{ name: 'edit', title: 'Edit...', seperator: true },
Expand All @@ -31,9 +34,15 @@ export const RNAContextMenu = () => {
switch (id) {
case 'duplicateandedit':
props.duplicatePreset(activePresetForContextMenu);
if (selectedTabIndex !== RNA_TAB_INDEX) {
dispatch(setSelectedTabIndex(RNA_TAB_INDEX));
}
break;
case 'edit':
props.editPreset(activePresetForContextMenu);
if (selectedTabIndex !== RNA_TAB_INDEX) {
dispatch(setSelectedTabIndex(RNA_TAB_INDEX));
}
break;
case 'deletepreset':
dispatch(openModal('delete'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ describe('Delete component', () => {
activePresetForContextMenu: { presetInList: preset, name: 'name' },
presets: [preset],
},
editor: {
editor: {
events: {
selectPreset: { dispatch: () => true },
},
},
},
}),
);
const deleteButton = screen.getByTitle('Delete');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import { Modal } from 'components/shared/modal';
import { useCallback } from 'react';
import { useAppDispatch, useAppSelector } from 'hooks';
import {
createNewPreset,
deletePreset,
selectActivePresetForContextMenu,
selectPresets,
setActivePreset,
setIsEditMode,
} from 'state/rna-builder';
import { StyledActionButton } from 'components/modal/Delete/styledComponents';
import styled from '@emotion/styled';
import { selectEditor } from 'state/common';

export interface Props {
onClose: () => void;
Expand All @@ -37,10 +37,10 @@ const DeleteTextWrapper = styled.div`

const Delete = ({ isModalOpen, onClose }: Props) => {
const dispatch = useAppDispatch();
const presets = useAppSelector(selectPresets);
const activePresetForContextMenu = useAppSelector(
selectActivePresetForContextMenu,
);
const editor = useAppSelector(selectEditor);
const onCloseCallback = useCallback(() => {
onClose();
}, [onClose]);
Expand All @@ -53,9 +53,8 @@ const Delete = ({ isModalOpen, onClose }: Props) => {
onCloseCallback();
dispatch(deletePreset(activePresetForContextMenu));
dispatch(setIsEditMode(false));
if (presets.length !== 0) {
dispatch(setActivePreset(presets[0]));
}
dispatch(createNewPreset());
editor.events.selectPreset.dispatch(null);
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const monomerData = {
MonomerNaturalAnalogCode: 'A',
MonomerType: 'MONOMER',
BranchMonomer: '',
MonomerCaps: { R1: 'H' },
MonomerCode: '',
MonomerName: '',
Name: 'First peptide',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,81 +13,67 @@
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
import { ChangeEvent } from 'react';
import React, { ChangeEvent, useRef } from 'react';
import { Tabs } from 'components/shared/Tabs';
import styled from '@emotion/styled';
import { tabsContent } from 'components/monomerLibrary/tabsContent';
import { useAppDispatch } from 'hooks';
import { useAppDispatch, useAppSelector } from 'hooks';
import { setSearchFilter } from 'state/library';
import { Icon } from 'ketcher-react';
import { IRnaPreset } from './RnaBuilder/types';
import {
savePreset,
selectPresets,
setActivePreset,
setIsEditMode,
setUniqueNameError,
} from 'state/rna-builder';
import { scrollToSelectedPreset } from './RnaBuilder/RnaEditor/RnaEditor';
import {
MonomerLibraryContainer,
MonomerLibraryHeader,
MonomerLibrarySearch,
MonomerLibraryTitle,
} from './styles';

export const MONOMER_LIBRARY_WIDTH = '254px';

const MonomerLibraryContainer = styled.div(({ theme }) => ({
width: MONOMER_LIBRARY_WIDTH,
height: 'calc(100% - 16px)',
backgroundColor: theme.ketcher.color.background.primary,
boxShadow: '0px 2px 5px rgba(103, 104, 132, 0.15)',
display: 'flex',
flexDirection: 'column',
borderRadius: '4px',
}));

const MonomerLibraryTitle = styled.h3(({ theme }) => ({
margin: 0,
padding: 0,
fontSize: theme.ketcher.font.size.regular,
fontWeight: theme.ketcher.font.weight.regular,
}));

const MonomerLibraryHeader = styled.div(() => ({
padding: '12px',
position: 'relative',
}));

const MonomerLibrarySearch = styled.div(({ theme }) => ({
padding: '12px 0',

'& > div': {
background: theme.ketcher.color.input.background.default,
display: 'flex',
height: '24px',
flexDirection: 'row',
border: '1px solid transparent',
borderRadius: '4px',
padding: '0 4px',

'& > span': {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},

'&:has(input:focus)': {
outline: `1px solid ${theme.ketcher.color.input.border.focus}`,
},

'& > input': {
background: 'transparent',
border: 'none',
padding: '0 0 0 8px',
margin: 0,
flex: 1,

'&:focus': {
outline: 'none',
},
},
},
}));

const MonomerLibrary = () => {
const MonomerLibrary = React.memo(() => {
const presetsRef = useRef<IRnaPreset[]>([]);
const dispatch = useAppDispatch();

useAppSelector(selectPresets, (presets) => {
presetsRef.current = presets;
return true;
});
const filterResults = (event: ChangeEvent<HTMLInputElement>) => {
dispatch(setSearchFilter(event.target.value));
};

const duplicatePreset = (preset?: IRnaPreset) => {
const name = `${preset?.name}_Copy`;
const presetWithSameName = presetsRef.current.find(
(preset) => preset.name === name,
);
if (presetWithSameName) {
dispatch(setUniqueNameError(name));
return;
}

const duplicatedPreset = {
...preset,
presetInList: undefined,
name: presetWithSameName ? `${name}_Copy` : name,
default: false,
favorite: false,
};
dispatch(setActivePreset(duplicatedPreset));
dispatch(savePreset(duplicatedPreset));
dispatch(setIsEditMode(true));
scrollToSelectedPreset(preset?.name);
};

const editPreset = (preset: IRnaPreset) => {
dispatch(setActivePreset(preset));
dispatch(setIsEditMode(true));
};

return (
<MonomerLibraryContainer data-testid="monomer-library">
<MonomerLibraryHeader>
Expand All @@ -105,9 +91,9 @@ const MonomerLibrary = () => {
</div>
</MonomerLibrarySearch>
</MonomerLibraryHeader>
<Tabs tabs={tabsContent} />
<Tabs tabs={tabsContent(duplicatePreset, editPreset)} />
</MonomerLibraryContainer>
);
};
});

export { MonomerLibrary };
Loading

0 comments on commit ceb5a86

Please sign in to comment.