Skip to content

Commit

Permalink
#3328 - Add bond custom query field
Browse files Browse the repository at this point in the history
  • Loading branch information
AKZhuk committed Sep 22, 2023
1 parent c6efc38 commit 0d6405a
Show file tree
Hide file tree
Showing 15 changed files with 253 additions and 52 deletions.
1 change: 1 addition & 0 deletions ketcher-autotests/tests/utils/canvas/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type BondAttributes = {
topology?: number;
type?: BondType;
xxx?: string;
customQuery?: string | null;
};

export type AtomXy = AtomAttributes & { x: number; y: number };
Expand Down
4 changes: 2 additions & 2 deletions packages/ketcher-core/src/application/render/draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ function reactingCenter(
return paper.path(pathDesc).attr(options.lineattr);
}

function topologyMark(
function bondMark(
paper: RaphaelPaper,
point: Vec2,
mark: string | null,
Expand Down Expand Up @@ -1612,7 +1612,7 @@ export default {
bondHydrogen,
bondDative,
reactingCenter,
topologyMark,
bondMark,
radicalCap,
radicalBullet,
bracket,
Expand Down
19 changes: 12 additions & 7 deletions packages/ketcher-core/src/application/render/restruct/rebond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ class ReBond extends ReObject {
);
}
const topology: any = {};
topology.path = getTopologyMark(render, this, hb1, hb2);
topology.path = getBondMark(render, this, hb1, hb2);
if (topology.path) {
topology.rbb = util.relBox(topology.path.getBBox());
restruct.addReObjectPath(
Expand Down Expand Up @@ -1241,7 +1241,7 @@ function getReactingCenterPath(
return draw.reactingCenter(render.paper, p, render.options);
}

function getTopologyMark(
function getBondMark(
render: Render,
bond: ReBond,
hb1: HalfBond,
Expand All @@ -1250,10 +1250,15 @@ function getTopologyMark(
// eslint-disable-line max-statements
const options = render.options;
let mark: string | null = null;

if (bond.b.topology === Bond.PATTERN.TOPOLOGY.RING) mark = 'rng';
else if (bond.b.topology === Bond.PATTERN.TOPOLOGY.CHAIN) mark = 'chn';
else return null;
if (bond.b.customQuery) {
mark = bond.b.customQuery;
} else if (bond.b.topology === Bond.PATTERN.TOPOLOGY.RING) {
mark = 'rng';
} else if (bond.b.topology === Bond.PATTERN.TOPOLOGY.CHAIN) {
mark = 'chn';
} else {
return null;
}

const a = hb1.p;
const b = hb2.p;
Expand All @@ -1268,7 +1273,7 @@ function getTopologyMark(
if (bond.b.type === Bond.PATTERN.TYPE.TRIPLE) fixed += options.bondSpace;
const p = c.add(new Vec2(n.x * (s.x + fixed), n.y * (s.y + fixed)));

return draw.topologyMark(render.paper, p, mark, options);
return draw.bondMark(render.paper, p, mark, options);
}

function getIdsPath(
Expand Down
19 changes: 15 additions & 4 deletions packages/ketcher-core/src/domain/entities/bond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ enum CIP {
}

export interface BondAttributes {
reactingCenterStatus?: number;
topology?: number;
reactingCenterStatus?: number | null;
topology?: number | null;
customQuery?: string | null;
stereo?: number;
xxx?: string;
type: number;
Expand Down Expand Up @@ -84,15 +85,17 @@ export class Bond {
topology: Bond.PATTERN.TOPOLOGY.EITHER,
reactingCenterStatus: Bond.PATTERN.REACTING_CENTER.UNMARKED,
cip: null,
customQuery: null,
};

begin: number;
end: number;
readonly type: number;
readonly xxx: string;
readonly stereo: number;
readonly topology: number;
readonly reactingCenterStatus: number;
readonly topology: number | null;
readonly reactingCenterStatus: number | null;
customQuery: string | null;
len: number;
sb: number;
sa: number;
Expand All @@ -110,6 +113,7 @@ export class Bond {
this.xxx = attributes.xxx || '';
this.stereo = Bond.PATTERN.STEREO.NONE;
this.topology = Bond.PATTERN.TOPOLOGY.EITHER;
this.customQuery = null;
this.reactingCenterStatus = 0;
this.cip = attributes.cip ?? null;
this.len = 0;
Expand All @@ -120,6 +124,13 @@ export class Bond {

if (attributes.stereo) this.stereo = attributes.stereo;
if (attributes.topology) this.topology = attributes.topology;
if (attributes.customQuery) {
this.customQuery = attributes.customQuery;
this.type = 8;
this.reactingCenterStatus = null;
this.topology = null;
}

if (attributes.reactingCenterStatus) {
this.reactingCenterStatus = attributes.reactingCenterStatus;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export function bondToStruct(source, atomOffset = 0) {
ifDef(params, 'reactingCenterStatus', source.center);
ifDef(params, 'stereo', source.stereo);
ifDef(params, 'cip', source.cip);
ifDef(params, 'customQuery', source.customQuery);
// if (params.stereo)
// params.stereo = params.stereo > 1 ? params.stereo * 2 : params.stereo;
// params.xxx = 0;
Expand Down
51 changes: 33 additions & 18 deletions packages/ketcher-core/src/domain/serializers/ket/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,8 @@
},
"bond": {
"type": "object",
"required": ["atoms", "type"],
"required": ["atoms"],
"properties": {
"type": {
"type": "integer",
"enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
"atoms": {
"type": "array",
"minItems": 2,
Expand All @@ -272,18 +268,6 @@
"minimum": 0
}
},
"stereo": {
"type": "integer",
"enum": [0, 1, 3, 4, 6]
},
"topology": {
"type": "integer",
"enum": [0, 1, 2]
},
"center": {
"type": "integer",
"enum": [0, -1, 1, 2, 4, 8, 12]
},
"stereobox": {
"type": "integer",
"enum": [0, 1]
Expand All @@ -292,7 +276,38 @@
"type": "string",
"enum": ["Z", "E"]
}
}
},
"oneOf": [
{
"required": ["type"],
"properties": {
"type": {
"type": "integer",
"enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
"stereo": {
"type": "integer",
"enum": [0, 1, 3, 4, 6]
},
"topology": {
"type": "integer",
"enum": [0, 1, 2]
},
"center": {
"type": "integer",
"enum": [0, -1, 1, 2, 4, 8, 12]
}
}
},
{
"required": ["customQuery"],
"properties": {
"customQuery": {
"type": "string"
}
}
}
]
},
"rgroup": {
"type": "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,16 @@ function atomListToKet(source) {

function bondToKet(source) {
const result = {};

ifDef(result, 'type', source.type);
if (source.customQuery) {
ifDef(result, 'customQuery', source.customQuery);
} else {
ifDef(result, 'type', source.type);
ifDef(result, 'stereo', source.stereo, 0);
ifDef(result, 'topology', source.topology, 0);
ifDef(result, 'center', source.reactingCenterStatus, 0);
ifDef(result, 'cip', source.cip, '');
}
ifDef(result, 'atoms', [source.begin, source.end]);
ifDef(result, 'stereo', source.stereo, 0);
ifDef(result, 'topology', source.topology, 0);
ifDef(result, 'center', source.reactingCenterStatus, 0);
ifDef(result, 'cip', source.cip, '');

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ interface Props {
value?: string;
multiple?: boolean;
disabled?: boolean;
formName?: string;
name?: string;
}

const ChevronIcon = ({ className }) => (
Expand All @@ -47,6 +49,8 @@ const Select = ({
multiple = false,
disabled,
options,
formName,
name,
}: Props) => {
const [currentValue, setCurrentValue] = useState<Option>();

Expand Down Expand Up @@ -86,6 +90,9 @@ const Select = ({
value={option.value}
key={option.value}
disableRipple={true}
className={clsx({
[`dropdown-${formName}_${name}`]: formName,
})}
>
{option.label}
</MenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Form extends Component {
const initialState = { ...init, init: true };
onUpdate(initialState, valid, errs);
}
this.updateState = this.updateState.bind(this);
}

componentDidUpdate(prevProps) {
Expand All @@ -53,7 +54,8 @@ class Form extends Component {
} = this.props;
if (
(schema.key && schema.key !== prevProps.schema.key) ||
(rest.customValid !== prevProps.customValid && schema.title === 'Atom')
(rest.customValid !== prevProps.customValid &&
(schema.title === 'Atom' || schema.title === 'Bond'))
) {
this.schema = propSchema(schema, rest);
this.schema.serialize(result); // hack: valid first state
Expand Down Expand Up @@ -196,7 +198,12 @@ function CustomQueryField(props) {
setAnchorEl(null);
}, []);
const handleCheckboxChange = (value) => {
onCheckboxChange(value, stateStore.props.result, fieldOpts.onChange);
onCheckboxChange(
value,
stateStore.props.result,
fieldOpts.onChange,
stateStore.updateState,
);
};

return (
Expand Down
12 changes: 8 additions & 4 deletions packages/ketcher-react/src/script/ui/data/convert/structconv.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,22 @@ function toRlabel(values) {
export function fromBond(sbond) {
const type = sbond.type;
const stereo = sbond.stereo;
const isCustomQuery = sbond.customQuery !== null;
return {
type: fromBondType(type, stereo),
topology: sbond.topology || 0,
center: sbond.reactingCenterStatus || 0,
type: isCustomQuery ? '' : fromBondType(type, stereo),
topology: sbond.topology,
center: sbond.reactingCenterStatus,
customQuery: !isCustomQuery ? '' : sbond.customQuery.toString(),
};
}

export function toBond(bond) {
const isCustomQuery = bond.customQuery !== '';
return {
topology: bond.topology,
reactingCenterStatus: bond.center,
...toBondType(bond.type),
customQuery: !isCustomQuery ? null : bond.customQuery,
...toBondType(isCustomQuery ? 'any' : bond.type),
};
}

Expand Down
13 changes: 10 additions & 3 deletions packages/ketcher-react/src/script/ui/data/schema/struct-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,21 @@ export const bond = {
},
topology: {
title: 'Topology',
enum: [0, 1, 2],
enumNames: ['Either', 'Ring', 'Chain'],
enum: [null, 0, 1, 2],
enumNames: ['', 'Either', 'Ring', 'Chain'],
default: 0,
},
customQuery: {
title: 'Custom Query',
pattern: '[^ ]',
type: 'string',
invalidMessage: 'Invalid custom query',
},
center: {
title: 'Reacting Center',
enum: [0, -1, 1, 2, 4, 8, 12], // 5, 9, 13
enum: [null, 0, -1, 1, 2, 4, 8, 12], // 5, 9, 13
enumNames: [
'',
'Unmarked',
'Not center',
'Center',
Expand Down
1 change: 1 addition & 0 deletions packages/ketcher-react/src/script/ui/state/modal/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const formsState = {
type: 'single',
topology: 0,
center: 0,
customQuery: null,
},
},
check: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ const useBondTypeChange = () => {
const molecule = editor.render.ctab;
const bondIds = props?.bondIds || [];
const bondProps = tools[id].action.opts;

const isCustomQuery = molecule.bonds.get(bondIds[0])?.b.customQuery;
if (isCustomQuery) {
bondProps.customQuery = null;
bondProps.topology = 0;
bondProps.reactingCenterStatus = 0;
}
editor.update(fromBondsAttrs(molecule, bondIds, bondProps));
},
[getKetcherInstance],
Expand Down
Loading

0 comments on commit 0d6405a

Please sign in to comment.