1
- import React from 'react'
2
- import { connect } from 'react-redux'
3
-
4
- import { Dialog } from '../../views/components'
5
1
import Form , { Field } from '../../component/form/form'
6
- import { StereoLabel } from 'ketcher-core'
7
-
8
- export const predefinedStereoGroups = {
9
- [ StereoLabel . And ] : {
10
- min : 1 ,
11
- max : 2
12
- } ,
13
- [ StereoLabel . Or ] : {
14
- min : 1 ,
15
- max : 2
16
- }
17
- } as const
18
-
19
- export function getPredefinedStereoLabels ( stereoLabel : StereoLabel ) : string [ ] {
20
- const min = predefinedStereoGroups [ stereoLabel ] . min
21
- const max = predefinedStereoGroups [ stereoLabel ] . max
2
+ import { StereoLabel , Struct } from 'ketcher-core'
22
3
23
- return new Array ( max - min + 1 )
24
- . fill ( null )
25
- . map ( ( _ , index ) => stereoLabel + ( min + index ) )
26
- }
27
-
28
- const enhancedStereoSchema = {
29
- title : 'Enhanced Stereo' ,
30
- type : 'object' ,
31
- properties : {
32
- type : {
33
- title : 'Stereo Label' ,
34
- enum : [
35
- StereoLabel . Abs ,
36
- ...getPredefinedStereoLabels ( StereoLabel . And ) ,
37
- StereoLabel . And ,
38
- ...getPredefinedStereoLabels ( StereoLabel . Or ) ,
39
- StereoLabel . Or
40
- ] ,
41
- enumNames : [
42
- 'ABS' ,
43
- ...getPredefinedStereoLabels ( StereoLabel . And ) . map ( stereoLabel =>
44
- stereoLabel . replace ( StereoLabel . And , 'AND' )
45
- ) ,
46
- 'AND...' ,
47
- ...getPredefinedStereoLabels ( StereoLabel . Or ) . map ( stereoLabel =>
48
- stereoLabel . toUpperCase ( )
49
- ) ,
50
- 'OR...'
51
- ]
52
- } ,
53
- andNumber : {
54
- type : 'integer' ,
55
- minimum : 1 ,
56
- invalidMessage : 'Only positive integer'
57
- } ,
58
- orNumber : {
59
- type : 'integer' ,
60
- minimum : 1 ,
61
- invalidMessage : 'Only positive integer'
62
- }
63
- }
64
- }
4
+ import { Dialog } from '../../views/components'
5
+ import React from 'react'
6
+ import { connect } from 'react-redux'
7
+ import { range } from 'lodash'
65
8
66
9
interface EnhancedStereoResult {
67
10
andNumber : number
@@ -79,6 +22,7 @@ interface EnhancedStereoProps {
79
22
className : string
80
23
init : EnhancedStereoResult & { init ?: true }
81
24
formState : EnhancedStereoFormState
25
+ struct : Struct
82
26
}
83
27
84
28
interface EnhancedStereoCallProps {
@@ -89,24 +33,31 @@ interface EnhancedStereoCallProps {
89
33
type Props = EnhancedStereoProps & EnhancedStereoCallProps
90
34
91
35
const EnhancedStereo : React . FC < Props > = props => {
92
- const { formState, init, ...rest } = props
36
+ const { struct , formState, init, ...rest } = props
93
37
const { result, valid } = formState
94
38
95
- const handleChange = (
96
- stereoLabel : StereoLabel ,
97
- newState : EnhancedStereoResult
98
- ) : EnhancedStereoResult => {
99
- const defaultOrNumber = predefinedStereoGroups [ StereoLabel . Or ] . max + 1
100
- const defaultAndNumber = predefinedStereoGroups [ StereoLabel . And ] . max + 1
39
+ const stereoLabels : Array < string > = findStereLabels (
40
+ struct ,
41
+ Array . from ( struct . atoms . keys ( ) )
42
+ )
101
43
102
- if ( andNumberDisabled ( stereoLabel ) ) {
103
- newState . andNumber = defaultAndNumber
104
- }
105
- if ( orNumberDisabled ( stereoLabel ) ) {
106
- newState . orNumber = defaultOrNumber
44
+ const maxAnd : number = maxOfAnds ( stereoLabels )
45
+ const maxOr : number = maxOfOrs ( stereoLabels )
46
+
47
+ const enhancedStereoSchema = {
48
+ title : 'Enhanced Stereo' ,
49
+ type : 'object' ,
50
+ properties : {
51
+ type : {
52
+ type : 'string'
53
+ } ,
54
+ andNumber : {
55
+ type : 'integer'
56
+ } ,
57
+ orNumber : {
58
+ type : 'integer'
59
+ }
107
60
}
108
-
109
- return newState
110
61
}
111
62
112
63
return (
@@ -116,74 +67,104 @@ const EnhancedStereo: React.FC<Props> = props => {
116
67
params = { rest }
117
68
result = { ( ) => result }
118
69
valid = { ( ) => valid }
119
- buttons = { [ 'OK ' , 'Close ' ] } >
70
+ buttons = { [ 'Cancel ' , 'OK ' ] } >
120
71
< Form schema = { enhancedStereoSchema } init = { init } { ...formState } >
121
- < Field
122
- name = "type"
123
- component = { FieldSet }
124
- labelPos = { false }
125
- onChange = { handleChange }
126
- />
127
- </ Form >
128
- </ Dialog >
129
- )
130
- }
131
-
132
- interface FieldSetProps {
133
- name : string
134
- schema : any
135
- value : StereoLabel
136
- onChange : ( value : string ) => void
137
- type ?: string
138
- }
139
-
140
- const FieldSet : React . FC < FieldSetProps > = props => {
141
- const { schema, value, onChange, type = 'radio' , ...rest } = props
142
-
143
- return (
144
- < fieldset >
145
- { schema . enum . map ( ( val , index ) => (
146
- < li key = { schema . enumNames [ index ] } className = "stereo-label-item" >
147
- < label className = "stereo-label-name" >
148
- < input
149
- type = { type }
150
- checked = { val === value }
151
- value = { val }
152
- onChange = { ( ) => onChange ( val ) }
153
- { ...rest }
72
+ < fieldset >
73
+ < label className = "stereo-label-item" >
74
+ < Field
75
+ name = "type"
76
+ labelPos = { false }
77
+ type = "radio"
78
+ value = { StereoLabel . Abs }
79
+ checked = { result . type === StereoLabel . Abs }
154
80
/>
155
- { schema . enumNames [ index ] }
81
+ ABS
156
82
</ label >
157
- { val === StereoLabel . And && (
83
+ { maxAnd !== 0 && (
84
+ < label className = "stereo-label-item" >
85
+ < Field
86
+ name = "type"
87
+ labelPos = { false }
88
+ type = "radio"
89
+ value = { StereoLabel . And }
90
+ checked = { result . type === StereoLabel . And }
91
+ />
92
+ Add to AND
93
+ < Field
94
+ name = "andNumber"
95
+ schema = { range ( 1 , maxAnd + 1 ) }
96
+ type = "text"
97
+ className = "label-group-select"
98
+ />
99
+ Group
100
+ </ label >
101
+ ) }
102
+ { maxOr !== 0 && (
103
+ < label className = "stereo-label-item" >
104
+ < Field
105
+ name = "type"
106
+ labelPos = { false }
107
+ type = "radio"
108
+ value = { StereoLabel . Or }
109
+ checked = { result . type === StereoLabel . Or }
110
+ />
111
+ Add to OR
112
+ < Field
113
+ name = "orNumber"
114
+ schema = { range ( 1 , maxOr + 1 ) }
115
+ type = "text"
116
+ className = "label-group-select"
117
+ />
118
+ Group
119
+ </ label >
120
+ ) }
121
+ < label className = "stereo-label-item" >
158
122
< Field
159
- name = "andNumber "
160
- type = "text"
161
- className = "label-group-value "
162
- disabled = { andNumberDisabled ( value ) }
123
+ name = "type "
124
+ labelPos = { false }
125
+ type = "radio "
126
+ value = { `& ${ maxOr + 1 } ` }
163
127
/>
164
- ) }
165
- { val === StereoLabel . Or && (
128
+ Create new AND Group
129
+ </ label >
130
+ < label className = "stereo-label-item" >
166
131
< Field
167
- name = "orNumber "
168
- type = "text"
169
- className = "label-group-value "
170
- disabled = { orNumberDisabled ( value ) }
132
+ name = "type "
133
+ labelPos = { false }
134
+ type = "radio "
135
+ value = { `or ${ maxOr + 1 } ` }
171
136
/>
172
- ) }
173
- </ li >
174
- ) ) }
175
- </ fieldset >
137
+ Create new OR Group
138
+ </ label >
139
+ </ fieldset >
140
+ </ Form >
141
+ </ Dialog >
142
+ )
143
+ }
144
+
145
+ // TODO: Move the function below to Struct class
146
+ function findStereLabels ( struct , aids ) : Array < string > {
147
+ const stereoIds = aids . filter (
148
+ aid => struct . atoms . get ( aid ) . stereoLabel !== null
176
149
)
150
+ return stereoIds . map ( aid => struct . atoms . get ( aid ) . stereoLabel )
177
151
}
178
152
179
- function andNumberDisabled ( stereoLabel : StereoLabel ) : boolean {
180
- return ! stereoLabel || stereoLabel !== StereoLabel . And || stereoLabel === null
153
+ function maxOfAnds ( stereLabels ) : number {
154
+ const numbers = stereLabels . map ( label => {
155
+ return label . match ( / & / ) ? + label . match ( / \d + / ) ?. join ( ) : 0
156
+ } )
157
+ return Math . max ( ...numbers )
181
158
}
182
159
183
- function orNumberDisabled ( stereoLabel : StereoLabel ) : boolean {
184
- return ! stereoLabel || stereoLabel !== StereoLabel . Or || stereoLabel === null
160
+ function maxOfOrs ( stereLabels ) : number {
161
+ const numbers = stereLabels . map ( label => {
162
+ return label . match ( / o r / ) ? + label . match ( / \d + / ) ?. join ( ) : 0
163
+ } )
164
+ return Math . max ( ...numbers )
185
165
}
186
166
187
- export default connect ( store => ( {
188
- formState : store . modal . form || { result : { } , valid : false }
167
+ export default connect ( state => ( {
168
+ formState : state . modal . form || { result : { } , valid : false } ,
169
+ struct : state . editor . struct ( )
189
170
} ) ) ( EnhancedStereo )
0 commit comments