diff --git a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts index 771f9423a4..b6c058526c 100644 --- a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts +++ b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts @@ -126,9 +126,9 @@ test.describe('Right-click menu', () => { await page.getByText('Ring bond count').click(); await takeEditorScreenshot(page); await page.getByRole('button', { name: 'As drawn' }).first().click(); - await page.getByText('Substitution count').click(); + await page.getByText('Aromaticity').click(); await takeEditorScreenshot(page); - await page.getByRole('button', { name: '6' }).last().click(); + await page.getByRole('button', { name: 'aliphatic' }).click(); await page.getByText('Unsaturated').first().click(); await takeEditorScreenshot(page); await page.getByRole('button', { name: 'Saturated' }).last().click(); diff --git a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-1-chromium-linux.png b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-1-chromium-linux.png index 7f5891a4bc..7a64e10cc1 100644 Binary files a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-1-chromium-linux.png and b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-1-chromium-linux.png differ diff --git a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-2-chromium-linux.png b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-2-chromium-linux.png index e2f873f554..8e42d71b6c 100644 Binary files a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-2-chromium-linux.png and b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-2-chromium-linux.png differ diff --git a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-3-chromium-linux.png b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-3-chromium-linux.png index d14b6cf5b4..7cf95426c5 100644 Binary files a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-3-chromium-linux.png and b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-3-chromium-linux.png differ diff --git a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-4-chromium-linux.png b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-4-chromium-linux.png index c4960acf8c..9b4bea1115 100644 Binary files a/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-4-chromium-linux.png and b/ketcher-autotests/tests/User-Interface/Right-Click-Menu/right-click.spec.ts-snapshots/Right-click-menu-Check-right-click-property-change-for-atoms-4-chromium-linux.png differ diff --git a/ketcher-autotests/tests/utils/canvas/types.ts b/ketcher-autotests/tests/utils/canvas/types.ts index f99fb275a2..2d0628d1df 100644 --- a/ketcher-autotests/tests/utils/canvas/types.ts +++ b/ketcher-autotests/tests/utils/canvas/types.ts @@ -4,7 +4,8 @@ export enum SORT_TYPE { ASC_X = 'ASC_X', ASC_Y = 'ASC_Y', } - +export type Aromaticity = 'aromatic' | 'aliphatic'; +export type Chirality = '@' | '@@' | '@?' | '@@?'; export type AtomAttributes = { label?: string; charge?: number; @@ -15,6 +16,15 @@ export type AtomAttributes = { explicitValence?: number; implicitH?: number; ringBondCount?: number; + aromaticity?: Aromaticity | null; + degree?: number | null; + implicitHCount?: number | null; + ringMembership?: number | null; + ringSize?: number | null; + connectivity?: number | null; + ringConnectivity?: number | null; + chirality?: Chirality | null; + atomicMass?: number | null; substitutionCount?: number; unsaturatedAtom?: number; hCount?: number; diff --git a/packages/ketcher-core/src/application/editor/actions/utils.ts b/packages/ketcher-core/src/application/editor/actions/utils.ts index babf6fc4cc..a5d2e5128f 100644 --- a/packages/ketcher-core/src/application/editor/actions/utils.ts +++ b/packages/ketcher-core/src/application/editor/actions/utils.ts @@ -23,6 +23,7 @@ import { selectionKeys } from '../shared/constants'; import { EditorSelection } from '../editor.types'; export type AtomAttributeName = keyof AtomAttributes; +export type AtomAttributeValue = AtomAttributes[AtomAttributeName]; export function atomGetAttr( restruct: ReStruct, diff --git a/packages/ketcher-core/src/application/render/restruct/reatom.ts b/packages/ketcher-core/src/application/render/restruct/reatom.ts index b0bf9560ed..593e920f2a 100644 --- a/packages/ketcher-core/src/application/render/restruct/reatom.ts +++ b/packages/ketcher-core/src/application/render/restruct/reatom.ts @@ -1071,29 +1071,83 @@ function getAamText(atom) { function getQueryAttrsText(atom) { let queryAttrsText = ''; - if (atom.a.ringBondCount !== 0) { - if (atom.a.ringBondCount > 0) { - queryAttrsText += 'rb' + atom.a.ringBondCount.toString(); - } else if (atom.a.ringBondCount === -1) queryAttrsText += 'rb0'; - else if (atom.a.ringBondCount === -2) queryAttrsText += 'rb*'; + const addSemicolon = () => { + if (queryAttrsText.length > 0) queryAttrsText += ';'; + }; + const { + ringBondCount, + substitutionCount, + unsaturatedAtom, + hCount, + aromaticity, + degree, + implicitHCount, + ringMembership, + ringSize, + connectivity, + ringConnectivity, + chirality, + atomicMass, + } = atom.a; + if (ringBondCount !== 0) { + if (ringBondCount > 0) { + queryAttrsText += 'rb' + ringBondCount.toString(); + } else if (ringBondCount === -1) queryAttrsText += 'rb0'; + else if (ringBondCount === -2) queryAttrsText += 'rb*'; else throw new Error('Ring bond count invalid'); } - if (atom.a.substitutionCount !== 0) { - if (queryAttrsText.length > 0) queryAttrsText += ','; - if (atom.a.substitutionCount > 0) { - queryAttrsText += 's' + atom.a.substitutionCount.toString(); - } else if (atom.a.substitutionCount === -1) queryAttrsText += 's0'; - else if (atom.a.substitutionCount === -2) queryAttrsText += 's*'; + if (substitutionCount !== 0) { + addSemicolon(); + if (substitutionCount > 0) { + queryAttrsText += 's' + substitutionCount.toString(); + } else if (substitutionCount === -1) queryAttrsText += 's0'; + else if (substitutionCount === -2) queryAttrsText += 's*'; else throw new Error('Substitution count invalid'); } - if (atom.a.unsaturatedAtom > 0) { - if (queryAttrsText.length > 0) queryAttrsText += ','; - if (atom.a.unsaturatedAtom === 1) queryAttrsText += 'u'; + if (unsaturatedAtom > 0) { + addSemicolon(); + if (unsaturatedAtom === 1) queryAttrsText += 'u'; else throw new Error('Unsaturated atom invalid value'); } - if (atom.a.hCount > 0) { - if (queryAttrsText.length > 0) queryAttrsText += ','; - queryAttrsText += 'H' + (atom.a.hCount - 1).toString(); + if (hCount > 0) { + addSemicolon(); + queryAttrsText += 'H' + (hCount - 1).toString(); + } + if (aromaticity !== null) { + addSemicolon(); + queryAttrsText += aromaticity === 'aromatic' ? 'a' : 'A'; + } + if (degree !== null) { + addSemicolon(); + queryAttrsText += `D${degree}`; + } + if (implicitHCount !== null) { + addSemicolon(); + queryAttrsText += `h${implicitHCount}`; + } + if (ringMembership !== null) { + addSemicolon(); + queryAttrsText += `R${ringMembership}`; + } + if (ringSize !== null) { + addSemicolon(); + queryAttrsText += `r${ringSize}`; + } + if (connectivity !== null) { + addSemicolon(); + queryAttrsText += `X${connectivity}`; + } + if (ringConnectivity !== null) { + addSemicolon(); + queryAttrsText += `x${ringConnectivity}`; + } + if (chirality !== null) { + addSemicolon(); + queryAttrsText += chirality; + } + if (atomicMass !== null) { + addSemicolon(); + queryAttrsText += `${atomicMass}`; } return queryAttrsText; } diff --git a/packages/ketcher-core/src/domain/entities/atom.ts b/packages/ketcher-core/src/domain/entities/atom.ts index 426aecb4d7..4c4b4da90e 100644 --- a/packages/ketcher-core/src/domain/entities/atom.ts +++ b/packages/ketcher-core/src/domain/entities/atom.ts @@ -56,6 +56,8 @@ enum CIP { r = 'r', } +export type Aromaticity = 'aromatic' | 'aliphatic'; +export type Chirality = '@' | '@@' | '@?' | '@@?'; export interface AtomAttributes { stereoParity?: number; stereoLabel?: string | null; @@ -68,6 +70,14 @@ export interface AtomAttributes { unsaturatedAtom?: number; substitutionCount?: number; ringBondCount?: number; + aromaticity?: Aromaticity | null; + degree?: number | null; + ringMembership?: number | null; + ringSize?: number | null; + connectivity?: number | null; + ringConnectivity?: number | null; + chirality?: Chirality | null; + atomicMass?: number | null; explicitValence?: number; /** * Rgroup member attachment points @@ -125,6 +135,14 @@ export class Atom { substitutionCount: 0, unsaturatedAtom: 0, hCount: 0, + aromaticity: null, + degree: null, + ringMembership: null, + ringSize: null, + connectivity: null, + ringConnectivity: null, + chirality: null, + atomicMass: null, atomList: null, invRet: 0, exactChangeFlag: 0, @@ -150,6 +168,14 @@ export class Atom { charge: number; explicitValence: number; ringBondCount: number; + aromaticity: Aromaticity | null; + degree: number | null; + ringMembership: number | null; + ringSize: number | null; + connectivity: number | null; + ringConnectivity: number | null; + chirality: Chirality | null; + atomicMass: number | null; unsaturatedAtom: number; substitutionCount: number; valence: number; @@ -212,6 +238,35 @@ export class Atom { attributes.ringBondCount, Atom.attrlist.ringBondCount, ); + this.aromaticity = getValueOrDefault( + attributes.aromaticity, + Atom.attrlist.aromaticity, + ); + this.degree = getValueOrDefault(attributes.degree, Atom.attrlist.degree); + this.ringMembership = getValueOrDefault( + attributes.ringMembership, + Atom.attrlist.ringMembership, + ); + this.ringSize = getValueOrDefault( + attributes.ringSize, + Atom.attrlist.ringSize, + ); + this.connectivity = getValueOrDefault( + attributes.connectivity, + Atom.attrlist.connectivity, + ); + this.ringConnectivity = getValueOrDefault( + attributes.ringConnectivity, + Atom.attrlist.ringConnectivity, + ); + this.chirality = getValueOrDefault( + attributes.chirality, + Atom.attrlist.chirality, + ); + this.atomicMass = getValueOrDefault( + attributes.atomicMass, + Atom.attrlist.atomicMass, + ); this.substitutionCount = getValueOrDefault( attributes.substitutionCount, Atom.attrlist.substitutionCount, diff --git a/packages/ketcher-core/src/domain/serializers/ket/fromKet/moleculeToStruct.ts b/packages/ketcher-core/src/domain/serializers/ket/fromKet/moleculeToStruct.ts index 259710b981..5bcdd88237 100644 --- a/packages/ketcher-core/src/domain/serializers/ket/fromKet/moleculeToStruct.ts +++ b/packages/ketcher-core/src/domain/serializers/ket/fromKet/moleculeToStruct.ts @@ -27,6 +27,7 @@ import { import { Elements } from 'domain/constants'; import { ifDef } from 'utilities'; import { mergeFragmentsToStruct } from './mergeFragmentsToStruct'; +import { AtomAttributeName } from 'application/editor'; export function toRlabel(values) { let res = 0; @@ -82,7 +83,19 @@ export function moleculeToStruct(ketItem: any): Struct { export function atomToStruct(source) { const params: any = {}; - + const queryAttribute: AtomAttributeName[] = [ + 'ringBondCount', + 'substitutionCount', + 'hCount', + 'aromaticity', + 'degree', + 'ringMembership', + 'connectivity', + 'ringSize', + 'ringConnectivity', + 'chirality', + 'atomicMass', + ]; ifDef(params, 'label', source.label); ifDef(params, 'alias', source.alias); ifDef(params, 'pp', { @@ -101,10 +114,11 @@ export function atomToStruct(source) { ifDef(params, 'stereoParity', source.stereoParity); ifDef(params, 'weight', source.weight); // query - ifDef(params, 'ringBondCount', source.ringBondCount); - ifDef(params, 'substitutionCount', source.substitutionCount); + queryAttribute.forEach((attributeName) => { + ifDef(params, attributeName, source[attributeName]); + }); ifDef(params, 'unsaturatedAtom', Number(Boolean(source.unsaturatedAtom))); - ifDef(params, 'hCount', source.hCount); + // reaction ifDef(params, 'aam', source.mapping); ifDef(params, 'invRet', source.invRet); diff --git a/packages/ketcher-core/src/domain/serializers/ket/toKet/moleculeToKet.ts b/packages/ketcher-core/src/domain/serializers/ket/toKet/moleculeToKet.ts index c54cf47620..b7179130bc 100644 --- a/packages/ketcher-core/src/domain/serializers/ket/toKet/moleculeToKet.ts +++ b/packages/ketcher-core/src/domain/serializers/ket/toKet/moleculeToKet.ts @@ -83,6 +83,15 @@ function atomToKet(source) { ifDef(result, 'substitutionCount', source.substitutionCount, 0); ifDef(result, 'unsaturatedAtom', !!source.unsaturatedAtom, false); ifDef(result, 'hCount', source.hCount, 0); + ifDef(result, 'aromaticity', source.aromaticity); + ifDef(result, 'degree', source.degree); + ifDef(result, 'ringMembership', source.ringMembership); + ifDef(result, 'connectivity', source.connectivity); + ifDef(result, 'ringSize', source.ringSize); + ifDef(result, 'ringConnectivity', source.ringConnectivity); + ifDef(result, 'chirality', source.chirality); + ifDef(result, 'atomicMass', source.atomicMass, 0); + // reaction ifDef(result, 'mapping', parseInt(source.aam), 0); ifDef(result, 'invRet', source.invRet, 0); diff --git a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx index bcfc48408c..0897ec7e59 100644 --- a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -28,7 +28,7 @@ export default function ButtonGroup({ {buttons.map(({ label, value: buttonValue }) => ( handleChange(event, buttonValue)} className={clsx(classes.button, { [classes.selected]: buttonValue === value, diff --git a/packages/ketcher-react/src/script/ui/data/convert/structconv.js b/packages/ketcher-react/src/script/ui/data/convert/structconv.js index 6d4146504c..e2162f2093 100644 --- a/packages/ketcher-react/src/script/ui/data/convert/structconv.js +++ b/packages/ketcher-react/src/script/ui/data/convert/structconv.js @@ -86,6 +86,15 @@ export function fromAtom(satom) { radical: satom.radical, invRet: satom.invRet, exactChangeFlag: !!satom.exactChangeFlag, + aromaticity: satom.aromaticity, + degree: satom.degree, + implicitHCount: satom.implicitHCount, + ringMembership: satom.ringMembership, + ringSize: satom.ringSize, + connectivity: satom.connectivity, + ringConnectivity: satom.ringConnectivity, + chirality: satom.chirality, + atomicMass: satom.atomicMass === null ? '' : satom.atomicMass.toString(), ringBondCount: satom.ringBondCount, substitutionCount: satom.substitutionCount, unsaturatedAtom: !!satom.unsaturatedAtom, @@ -108,6 +117,7 @@ export function toAtom(atom) { unsaturatedAtom: +(atom.unsaturatedAtom ?? false), }); if (charge !== undefined) conv.charge = charge; + conv.atomicMass = atom.atomicMass === '' ? null : Number(atom.atomicMass); return conv; } diff --git a/packages/ketcher-react/src/script/ui/data/schema/struct-schema.js b/packages/ketcher-react/src/script/ui/data/schema/struct-schema.js index 9f92c713bc..08245442d9 100644 --- a/packages/ketcher-react/src/script/ui/data/schema/struct-schema.js +++ b/packages/ketcher-react/src/script/ui/data/schema/struct-schema.js @@ -94,6 +94,74 @@ export const atom = { type: 'boolean', default: false, }, + aromaticity: { + title: 'Aromaticity', + enum: [null, 'aromatic', 'aliphatic'], + enumNames: ['', 'aromatic', 'aliphatic'], + default: 0, + }, + degree: { + title: 'Degree', + enum: [null, 0, 1, 2, 3, 4, 5, 6], + enumNames: ['', '0', '1', '2', '3', '4', '5', '6'], + default: 0, + }, + implicitHCount: { + title: 'Implicit H count', + enum: [null, 0, 1, 2, 3, 4], + enumNames: ['', '0', '1', '2', '3', '4'], + default: 0, + }, + ringMembership: { + title: 'Ring membership', + enum: [null, 0, 1, 2, 3, 4, 5], + enumNames: ['', '0', '1', '2', '3', '4', '5'], + default: 0, + }, + ringSize: { + title: 'Ring size', + enum: [null, 0, 1, 2, 3, 4, 5], + enumNames: ['', '0', '1', '2', '3', '4', '5'], + default: 0, + }, + connectivity: { + title: 'Connectivity', + enum: [null, 0, 1, 2, 3, 4, 5], + enumNames: ['', '0', '1', '2', '3', '4', '5'], + default: 0, + }, + ringConnectivity1: { + title: 'Ring connectivity', + enum: [null, 0, 1, 2, 3, 4, 5], + enumNames: ['', '0', '1', '2', '3', '4', '5'], + default: 0, + }, + ringConnectivity: { + title: 'Ring connectivity', + enum: [null, 0, 1, 2, 3, 4, 5], + enumNames: ['', '0', '1', '2', '3', '4', '5'], + default: null, + }, + chirality: { + title: 'Chirality', + enum: [null, '@', '@@', '@?', '@@?'], + enumNames: [ + '', + 'anticlockwise', + 'clockwise', + 'anticlockwise or unspecified', + 'clockwise or unspecified', + ], + default: 0, + }, + atomicMass: { + title: 'Atomic mass', + type: 'string', + pattern: '^([+]?)([0-9]{1,3}|1000)([+-]?)$|(^$)', + default: '', + maxLength: 5, + invalidMessage: 'Invalid atomic mass', + }, invRet: { title: 'Inversion', enum: [0, 1, 2], diff --git a/packages/ketcher-react/src/script/ui/state/modal/form.js b/packages/ketcher-react/src/script/ui/state/modal/form.js index dead835934..1ff98870bf 100644 --- a/packages/ketcher-react/src/script/ui/state/modal/form.js +++ b/packages/ketcher-react/src/script/ui/state/modal/form.js @@ -35,6 +35,15 @@ export const formsState = { radical: 0, ringBondCount: 0, substitutionCount: 0, + aromaticity: null, + degree: null, + implicitHCount: null, + ringMembership: null, + ringSize: null, + connectivity: null, + ringConnectivity: null, + chirality: null, + atomicMass: null, }, }, attachmentPoints: { diff --git a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less index f5f1df2cb7..43238093ca 100644 --- a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less +++ b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less @@ -46,7 +46,7 @@ } :global(.contexify_submenu) { - max-height: 300px; + max-height: 400px; overflow: auto; .scrollbar(); } diff --git a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/menuItems/AtomMenuItems.tsx b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/menuItems/AtomMenuItems.tsx index 2a9cd51adb..c7f4e76cde 100644 --- a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/menuItems/AtomMenuItems.tsx +++ b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/menuItems/AtomMenuItems.tsx @@ -9,11 +9,26 @@ import { updateSelectedAtoms } from 'src/script/ui/state/modal/atoms'; import { useAppContext } from 'src/hooks'; import Editor from 'src/script/editor'; import ButtonGroup from '../../../../../../components/ToggleButtonGroup/ToggleButtonGroup'; -import { atomGetAttr, AtomAttributeName } from 'ketcher-core'; +import { + atomGetAttr, + AtomAttributeName, + AtomAttributes, + AtomAttributeValue, +} from 'ketcher-core'; import { atom } from 'src/script/ui/data/schema/struct-schema'; const { ringBondCount, hCount, substitutionCount, unsaturatedAtom } = atom.properties; +const properties: Array = [ + 'aromaticity', + 'degree', + 'implicitHCount', + 'ringMembership', + 'ringSize', + 'connectivity', + 'ringConnectivity', +]; + const atomPropertiesForSubMenu: { title: string; key: AtomAttributeName; @@ -51,6 +66,16 @@ const atomPropertiesForSubMenu: { { label: 'Saturated', value: 0 }, ], }, + ...properties.map((name) => ({ + title: atom.properties[name].title, + key: name, + buttons: atom.properties[name].enumNames.map( + (label: string, id: number) => ({ + label, + value: atom.properties[name].enum[id], + }), + ), + })), ]; const AtomMenuItems: FC = (props) => { @@ -65,7 +90,10 @@ const AtomMenuItems: FC = (props) => { const { getKetcherInstance } = useAppContext(); const editor = getKetcherInstance().editor as Editor; - const updateAtomProperty = (key: AtomAttributeName, value: number) => { + const updateAtomProperty = ( + key: AtomAttributeName, + value: AtomAttributes[AtomAttributeName], + ) => { updateSelectedAtoms({ atoms: props.propsFromTrigger?.atomIds as number[], editor, @@ -76,8 +104,8 @@ const AtomMenuItems: FC = (props) => { const getPropertyValue = (key: AtomAttributeName) => { if (props.propsFromTrigger?.atomIds) { const atomId = props.propsFromTrigger?.atomIds[0] as number; - return Number(atomGetAttr(editor.render.ctab, atomId, key)); - } else return 0; + return atomGetAttr(editor.render.ctab, atomId, key); + } else return null; }; return ( @@ -108,10 +136,12 @@ const AtomMenuItems: FC = (props) => { {atomPropertiesForSubMenu.map(({ title, buttons, key }) => { return ( - + buttons={buttons} defaultValue={getPropertyValue(key)} - onClick={(value: number) => updateAtomProperty(key, value)} + onClick={(value: AtomAttributeValue) => + updateAtomProperty(key, value) + } > ); diff --git a/packages/ketcher-react/src/script/ui/views/modal/components/toolbox/Atom/Atom.tsx b/packages/ketcher-react/src/script/ui/views/modal/components/toolbox/Atom/Atom.tsx index ff2d865130..8cbc7914f6 100644 --- a/packages/ketcher-react/src/script/ui/views/modal/components/toolbox/Atom/Atom.tsx +++ b/packages/ketcher-react/src/script/ui/views/modal/components/toolbox/Atom/Atom.tsx @@ -21,7 +21,7 @@ import { FC, useCallback, useState } from 'react'; import { Dialog } from '../../../../components'; import ElementNumber from './ElementNumber'; -import { Elements } from 'ketcher-core'; +import { AtomAttributeName, Elements } from 'ketcher-core'; import { atom as atomSchema } from '../../../../../data/schema/struct-schema'; import { capitalize } from 'lodash/fp'; import classes from './Atom.module.less'; @@ -51,7 +51,28 @@ type Props = AtomProps & { }; const atomProps = atomSchema.properties; - +const querySpecificFields: Array<{ + name: AtomAttributeName; + component?: 'dropdown'; + labelPos?: 'before' | 'after'; + className?: string; +}> = [ + { name: 'ringBondCount', component: 'dropdown' }, + { name: 'hCount', component: 'dropdown' }, + { name: 'substitutionCount', component: 'dropdown' }, + { name: 'unsaturatedAtom', labelPos: 'before', className: classes.checkbox }, + { name: 'aromaticity', component: 'dropdown' }, + { name: 'degree', component: 'dropdown' }, + { name: 'implicitHCount', component: 'dropdown' }, + { name: 'ringMembership', component: 'dropdown' }, + { name: 'ringSize', component: 'dropdown' }, + { name: 'connectivity', component: 'dropdown' }, + { name: 'ringConnectivity', component: 'dropdown' }, + { name: 'chirality', component: 'dropdown' }, + { + name: 'atomicMass', + }, +]; const Atom: FC = (props: Props) => { const { formState, @@ -112,26 +133,20 @@ const Atom: FC = (props: Props) => { groupName: 'Query specific', component: (
- - - - + {querySpecificFields.map((field) => { + if (field.component === 'dropdown') { + return ( + + ); + } else { + return ; + } + })}
), },