diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/add-default-presets.spec.ts b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/add-default-presets.spec.ts index 4bcbbbf1dc..0216031b35 100644 --- a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/add-default-presets.spec.ts +++ b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/add-default-presets.spec.ts @@ -5,11 +5,14 @@ import { takePageScreenshot, waitForPageInit, } from '@utils'; +import { toggleRnaBuilderAccordion } from '@utils/macromolecules/rnaBuilder'; test.describe('Macromolecules default presets', () => { test.beforeEach(async ({ page }) => { await waitForPageInit(page); await turnOnMacromoleculesEditor(page); + await page.getByText('RNA').click(); + await toggleRnaBuilderAccordion(page); }); test('Check Guanine in default presets', async ({ page }) => { @@ -17,9 +20,6 @@ test.describe('Macromolecules default presets', () => { Test case: #2934 - rna builder: add default presets Description: Switch to Polymer Editor */ - await page.getByText('RNA').click(); - - await page.getByTestId('cancel-btn').click(); await page.getByTestId('G_G_R_P').click(); await takePageScreenshot(page); }); @@ -28,9 +28,6 @@ test.describe('Macromolecules default presets', () => { /* Test case: #2507 - Add RNA monomers to canvas (by click) */ - await page.getByText('RNA').click(); - await page.getByTestId('cancel-btn').click(); - await page.click('[data-testid="G_G_R_P"]'); await page.click('#polymer-editor-canvas'); diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts index 59c3b2fc6f..32f8ccc2cc 100644 --- a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts +++ b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts @@ -3,10 +3,12 @@ import { RNA_TAB } from '@constants/testIdConstants'; 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); } test.describe('Macromolecules delete RNA presets', () => { @@ -20,21 +22,15 @@ test.describe('Macromolecules delete RNA presets', () => { }); test('Should not delete default RNA preset', async ({ page }) => { - await page.getByTestId('cancel-btn').click(); - await page.getByTestId('A_A_R_P').click({ button: 'right' }); }); test('Delete copy RNA preset', async ({ page }) => { - await page.getByTestId('cancel-btn').click(); - await page.getByTestId('A_A_R_P').click({ button: 'right' }); - const duplicateAndEditButton = await page.getByTestId('duplicateandedit'); - await duplicateAndEditButton.click(); - await duplicateAndEditButton.waitFor({ state: 'hidden' }); + await page.getByTestId('duplicateandedit').click(); + await page.getByTestId('save-btn').click(); - await page.getByTestId('A_Copy_A_R_P').click(); await page.getByTestId('A_Copy_A_R_P').click({ button: 'right' }); await page.getByTestId('deletepreset').click(); diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-1-chromium-linux.png b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-1-chromium-linux.png index 6de147ebf0..3e6e992b2e 100644 Binary files a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-1-chromium-linux.png and b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-1-chromium-linux.png differ diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-2-chromium-linux.png b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-2-chromium-linux.png index 707ee07d49..e7b85c6b58 100644 Binary files a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-2-chromium-linux.png and b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Delete-copy-RNA-preset-2-chromium-linux.png differ diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Should-not-delete-default-RNA-preset-1-chromium-linux.png b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Should-not-delete-default-RNA-preset-1-chromium-linux.png index cc067382ad..a04bb4bff0 100644 Binary files a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Should-not-delete-default-RNA-preset-1-chromium-linux.png and b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/delete-preset.spec.ts-snapshots/Macromolecules-delete-RNA-presets-Should-not-delete-default-RNA-preset-1-chromium-linux.png differ diff --git a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/rna-layout.spec.ts b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/rna-layout.spec.ts index 42084ef842..318db106ec 100644 --- a/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/rna-layout.spec.ts +++ b/ketcher-autotests/tests/Macromolecule-editor/RNAEditor/rna-layout.spec.ts @@ -3,6 +3,7 @@ import { RNA_TAB } from '@constants/testIdConstants'; import { waitForPageInit } from '@utils/common'; import { takePageScreenshot } from '@utils'; import { turnOnMacromoleculesEditor } from '@utils/macromolecules'; +import { toggleRnaBuilderAccordion } from '@utils/macromolecules/rnaBuilder'; /* Test case: #3063 - Add e2e tests for Macromolecule editor @@ -10,6 +11,7 @@ Test case: #3063 - Add e2e tests for Macromolecule editor async function createRNA(page: Page) { await turnOnMacromoleculesEditor(page); await page.getByTestId(RNA_TAB).click(); + await toggleRnaBuilderAccordion(page); await page.fill('[placeholder="Name your structure"]', 'MyRNA'); await page.press('[placeholder="Name your structure"]', 'Enter'); } @@ -30,6 +32,6 @@ test.describe('RNA layout', () => { }); test('RNA Builder panel is collapsed', async ({ page }) => { - await page.getByText('RNA Builder').locator('button').click(); + await toggleRnaBuilderAccordion(page); }); }); diff --git a/ketcher-autotests/tests/utils/macromolecules/rnaBuilder.ts b/ketcher-autotests/tests/utils/macromolecules/rnaBuilder.ts new file mode 100644 index 0000000000..cb5371b9ac --- /dev/null +++ b/ketcher-autotests/tests/utils/macromolecules/rnaBuilder.ts @@ -0,0 +1,5 @@ +import { Page } from '@playwright/test'; + +export async function toggleRnaBuilderAccordion(page: Page) { + await page.getByText('RNA Builder').locator('button').click(); +} diff --git a/packages/ketcher-polymer-editor-react/src/components/contextMenu/RNAContextMenu.tsx b/packages/ketcher-polymer-editor-react/src/components/contextMenu/RNAContextMenu.tsx index d4bb0e30a8..9a9a1d998f 100644 --- a/packages/ketcher-polymer-editor-react/src/components/contextMenu/RNAContextMenu.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/contextMenu/RNAContextMenu.tsx @@ -3,12 +3,14 @@ import { openModal } from 'state/modal'; import { useAppDispatch, useAppSelector } from 'hooks'; import { ReactElement } from 'react'; import { CONTEXT_MENU_ID } from './types'; -import { selectActivePreset } from 'state/rna-builder'; +import { selectActivePresetForContextMenu } from 'state/rna-builder'; import { StyledMenu } from './styles'; export const RNAContextMenu = () => { const dispatch = useAppDispatch(); - const activePreset = useAppSelector(selectActivePreset); + const activePresetForContextMenu = useAppSelector( + selectActivePresetForContextMenu, + ); const RNAMenus = [ { name: 'duplicateandedit', title: 'Duplicate and Edit...' }, { name: 'edit', title: 'Edit...', seperator: true }, @@ -16,7 +18,7 @@ export const RNAContextMenu = () => { ]; const isItemDisabled = (name: string) => { - if (name === 'deletepreset' && activePreset?.default) { + if (name === 'deletepreset' && activePresetForContextMenu?.default) { return true; } return false; @@ -25,10 +27,10 @@ export const RNAContextMenu = () => { const handleMenuChange = ({ id, props }: ItemParams) => { switch (id) { case 'duplicateandedit': - props.duplicatePreset(); + props.duplicatePreset(activePresetForContextMenu); break; case 'edit': - props.activateEditMode(); + props.editPreset(activePresetForContextMenu); break; case 'deletepreset': dispatch(openModal('delete')); diff --git a/packages/ketcher-polymer-editor-react/src/components/modal/Delete/Delete.tsx b/packages/ketcher-polymer-editor-react/src/components/modal/Delete/Delete.tsx index 43e9b404e7..0d3059536b 100644 --- a/packages/ketcher-polymer-editor-react/src/components/modal/Delete/Delete.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/modal/Delete/Delete.tsx @@ -18,7 +18,7 @@ import { useCallback } from 'react'; import { useAppDispatch, useAppSelector } from 'hooks'; import { deletePreset, - selectActivePreset, + selectActivePresetForContextMenu, selectPresets, setActivePreset, setIsEditMode, @@ -33,7 +33,9 @@ export interface Props { const Delete = ({ isModalOpen, onClose }: Props) => { const dispatch = useAppDispatch(); const presets = useAppSelector(selectPresets); - const activePreset = useAppSelector(selectActivePreset); + const activePresetForContextMenu = useAppSelector( + selectActivePresetForContextMenu, + ); const onCloseCallback = useCallback(() => { onClose(); }, [onClose]); @@ -44,7 +46,7 @@ const Delete = ({ isModalOpen, onClose }: Props) => { const deleteHandler = () => { onCloseCallback(); - dispatch(deletePreset(activePreset)); + dispatch(deletePreset(activePresetForContextMenu)); dispatch(setIsEditMode(false)); if (presets.length !== 0) { dispatch(setActivePreset(presets[0])); @@ -60,7 +62,7 @@ const Delete = ({ isModalOpen, onClose }: Props) => { You are about to delete - "{activePreset.name}" RNA preset. + "{activePresetForContextMenu.name}" RNA preset. This operation cannot be undone. diff --git a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaAccordion/RnaAccordion.tsx b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaAccordion/RnaAccordion.tsx index ec5432dd69..7069a87051 100644 --- a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaAccordion/RnaAccordion.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaAccordion/RnaAccordion.tsx @@ -45,9 +45,11 @@ import { selectActivePreset, selectActivePresetMonomerGroup, selectActiveRnaBuilderItem, + selectIsActivePresetNewAndEmpty, selectIsEditMode, selectPresets, setActivePreset, + setActivePresetForContextMenu, setActivePresetMonomerGroup, setActiveRnaBuilderItem, setIsEditMode, @@ -74,11 +76,7 @@ interface IGroupsDataItem { }[]; } -export const RnaAccordion = ({ - libraryName, - duplicatePreset, - activateEditMode, -}) => { +export const RnaAccordion = ({ libraryName, duplicatePreset, editPreset }) => { const monomers = useAppSelector(selectFilteredMonomers); const items = selectMonomersInCategory(monomers, libraryName); const activeRnaBuilderItem = useAppSelector(selectActiveRnaBuilderItem); @@ -87,6 +85,9 @@ export const RnaAccordion = ({ const presets = useAppSelector(selectPresets); const isEditMode = useAppSelector(selectIsEditMode); const editor = useAppSelector(selectEditor); + const isActivePresetNewAndEmpty = useAppSelector( + selectIsActivePresetNewAndEmpty, + ); const [expandedAccordion, setExpandedAccordion] = useState(activeRnaBuilderItem); @@ -143,12 +144,12 @@ export const RnaAccordion = ({ }; const handleContextMenu = (preset: IRnaPreset) => (event: MouseEvent) => { - dispatch(setActivePreset(preset)); + dispatch(setActivePresetForContextMenu(preset)); show({ event, props: { duplicatePreset, - activateEditMode, + editPreset, }, }); }; @@ -170,6 +171,8 @@ export const RnaAccordion = ({ const selectPreset = (preset: IRnaPreset) => { dispatch(setActivePreset(preset)); editor.events.selectPreset.dispatch(preset); + if (preset === activePreset.presetInList) return; + dispatch(setIsEditMode(false)); }; const onClickNewPreset = () => { @@ -216,7 +219,7 @@ export const RnaAccordion = ({ - {isEditMode && } + {isEditMode && !isActivePresetNewAndEmpty && } ) : ( diff --git a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaBuilder.tsx b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaBuilder.tsx index f669c933c1..1b389a6227 100644 --- a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaBuilder.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaBuilder.tsx @@ -49,11 +49,11 @@ export const RnaBuilder = ({ libraryName }) => { dispatch(setDefaultPresets(defaultPresets)); }, [dispatch]); - const duplicatePreset = () => { + const duplicatePreset = (preset?: IRnaPreset) => { const duplicatedPreset = { - ...activePreset, + ...(preset || activePreset), presetInList: undefined, - name: `${activePreset.name}_Copy`, + name: `${preset?.name || activePreset.name}_Copy`, default: false, }; dispatch(setActivePreset(duplicatedPreset)); @@ -66,6 +66,11 @@ export const RnaBuilder = ({ libraryName }) => { dispatch(setIsEditMode(true)); }; + const editPreset = (preset: IRnaPreset) => { + dispatch(setActivePreset(preset)); + activateEditMode(); + }; + return ( { diff --git a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditor.tsx b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditor.tsx index 28a3bd02f7..499e7ccb54 100644 --- a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditor.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditor.tsx @@ -65,22 +65,27 @@ export const RnaEditor = ({ duplicatePreset, activateEditMode }) => { dispatch(setIsEditModeAction(value)); }; + const [expanded, setExpanded] = useState(false); + useEffect(() => { - if (activePreset) return; + if (activePreset) { + if (activePreset.name || isEditMode) setExpanded(true); + return; + } if (hasPresets) { dispatch(setActivePreset(presets[0])); } else { dispatch(createNewPreset()); dispatch(setActiveRnaBuilderItem(RnaBuilderPresetsItem.Presets)); - setIsEditMode(true); } - }, []); - - const [expanded, setExpanded] = useState(true); + }, [activePreset]); const expandEditor = () => { setExpanded(!expanded); + if (!activePreset.presetInList) { + setIsEditMode(true); + } }; useEffect(() => { diff --git a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditorCollapsed/RnaEditorCollapsed.tsx b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditorCollapsed/RnaEditorCollapsed.tsx index 39807d1e75..d006f66ca7 100644 --- a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditorCollapsed/RnaEditorCollapsed.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/RnaBuilder/RnaEditor/RnaEditorCollapsed/RnaEditorCollapsed.tsx @@ -25,13 +25,13 @@ export const RnaEditorCollapsed = ({ name, fullName, }: IRnaEditorCollapsedProps) => { - return ( + return name || fullName ? ( - - {name || fullName || 'Untitled'} - + {name || fullName} + ) : ( + <>> ); }; diff --git a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/monomerLibraryList/MonomerList.tsx b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/monomerLibraryList/MonomerList.tsx index 42b4995491..c50d93a161 100644 --- a/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/monomerLibraryList/MonomerList.tsx +++ b/packages/ketcher-polymer-editor-react/src/components/monomerLibrary/monomerLibraryList/MonomerList.tsx @@ -38,7 +38,6 @@ export type Group = { const MonomerList = ({ onItemClick, libraryName }: IMonomerListProps) => { const monomers = useAppSelector(selectFilteredMonomers); const activeTool = useAppSelector(selectEditorActiveTool); - const items = libraryName !== MONOMER_LIBRARY_FAVORITES ? selectMonomersInCategory(monomers, libraryName) diff --git a/packages/ketcher-polymer-editor-react/src/state/rna-builder/rnaBuilderSlice.ts b/packages/ketcher-polymer-editor-react/src/state/rna-builder/rnaBuilderSlice.ts index 8cb8ecdcca..b143049d56 100644 --- a/packages/ketcher-polymer-editor-react/src/state/rna-builder/rnaBuilderSlice.ts +++ b/packages/ketcher-polymer-editor-react/src/state/rna-builder/rnaBuilderSlice.ts @@ -32,6 +32,7 @@ interface IRnaBuilderState { activeRnaBuilderItem?: RnaBuilderItem | null; isEditMode: boolean; hasUniqueNameError: boolean; + activePresetForContextMenu: IRnaPreset | null; } const initialState: IRnaBuilderState = { @@ -40,6 +41,7 @@ const initialState: IRnaBuilderState = { activeRnaBuilderItem: null, isEditMode: false, hasUniqueNameError: false, + activePresetForContextMenu: null, }; export const monomerGroupToPresetGroup = { [MonomerGroups.BASES]: 'base', @@ -65,6 +67,12 @@ export const rnaBuilderSlice = createSlice({ presetInList: action.payload, }; }, + setActivePresetForContextMenu: ( + state, + action: PayloadAction, + ) => { + state.activePresetForContextMenu = action.payload; + }, setActivePresetName: (state, action: PayloadAction) => { state.activePreset!.name = action.payload; }, @@ -186,6 +194,22 @@ export const selectHasUniqueNameError = (state: RootState) => { return state.rnaBuilder.hasUniqueNameError; }; +export const selectIsActivePresetNewAndEmpty = (state: RootState): boolean => { + const activePreset = state.rnaBuilder.activePreset; + return ( + activePreset && + !activePreset.presetInList && + !activePreset.name && + !activePreset.sugar && + !activePreset.base && + !activePreset.phosphate + ); +}; + +export const selectActivePresetForContextMenu = (state: RootState) => { + return state.rnaBuilder.activePresetForContextMenu; +}; + export const { setActivePreset, setActivePresetName, @@ -197,6 +221,7 @@ export const { setIsEditMode, setHasUniqueNameError, setDefaultPresets, + setActivePresetForContextMenu, } = rnaBuilderSlice.actions; export const rnaBuilderReducer = rnaBuilderSlice.reducer;