Skip to content

Commit

Permalink
#1820 – adding salts and solvents tab
Browse files Browse the repository at this point in the history
  • Loading branch information
Nitvex committed Nov 29, 2022
1 parent 7cfb1e2 commit a236295
Show file tree
Hide file tree
Showing 9 changed files with 4,965 additions and 8 deletions.
4,782 changes: 4,782 additions & 0 deletions example/public/templates/salts-and-solvents.sdf

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/ketcher-core/src/domain/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
export * from './scale'
export * from './stereoValidator'
export * from './functionalGroupsProvider'
export * from './saltsAndSolventsProvider'
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/****************************************************************************
* Copyright 2021 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
import { Struct } from '../entities'

export class SaltsAndSolventsProvider {
// eslint-disable-next-line no-use-before-define
private static instance: SaltsAndSolventsProvider
saltsAndSolventsList: Struct[]
constructor() {
this.saltsAndSolventsList = []
}

public static getInstance(): SaltsAndSolventsProvider {
if (!SaltsAndSolventsProvider.instance) {
SaltsAndSolventsProvider.instance = new SaltsAndSolventsProvider()
}
return SaltsAndSolventsProvider.instance
}

public getSaltsAndSolventsList() {
return this.saltsAndSolventsList
}

public setSaltsAndSolventsList(list: Struct[]): void {
this.saltsAndSolventsList = list
}
}

2 changes: 2 additions & 0 deletions packages/ketcher-react/src/script/ui/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import AppModalContainer from '../views/modal'
import Editor from '../views/Editor'
import classes from './App.module.less'
import { initFGTemplates } from '../state/functionalGroups'
import { initSaltsAndSolventsTemplates } from '../state/saltsAndSolvents'
import { useSettingsContext, useSubscriptionOnEvents } from '../../../hooks'

interface AppCallProps {
Expand Down Expand Up @@ -57,6 +58,7 @@ const App = (props: Props) => {
useEffect(() => {
checkServer()
dispatch(initFGTemplates(staticResourcesUrl))
dispatch(initSaltsAndSolventsTemplates(staticResourcesUrl))
window.scrollTo(0, 0)
}, [])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { createSelector } from 'reselect'
import { omit } from 'lodash/fp'
import { onAction } from '../../state'
import { functionalGroupsSelector } from '../../state/functionalGroups/selectors'
import { saltsAndSolventsSelector } from '../../state/saltsAndSolvents/selectors'
import EmptySearchResult from '../../../ui/dialog/template/EmptySearchResult'

import Tabs from '@mui/material/Tabs'
Expand Down Expand Up @@ -73,7 +74,8 @@ interface TemplateLibProps {
lib: Array<Template>
selected: Template
mode: string
initialTab: number
initialTab: number,
saltsAndSolvents: Template[]
}

interface TemplateLibCallProps {
Expand All @@ -91,7 +93,8 @@ type Props = TemplateLibProps & TemplateLibCallProps

enum TemplateTabs {
TemplateLibrary = 0,
FunctionalGroupLibrary = 1
FunctionalGroupLibrary = 1,
SaltsAndSolvents = 2
}

export interface Result {
Expand All @@ -108,6 +111,7 @@ const filterLibSelector = createSelector(
)

const FUNCTIONAL_GROUPS = 'Functional Groups'
const SALTS_AND_SOLVENTS = 'Salts and Solvents'

const HeaderContent = () => (
<div className={classes.dialogHeader}>
Expand Down Expand Up @@ -144,6 +148,7 @@ const TemplateDialog: FC<Props> = (props) => {
initialTab,
functionalGroups,
lib: templateLib,
saltsAndSolvents,
...rest
} = props

Expand All @@ -154,13 +159,20 @@ const TemplateDialog: FC<Props> = (props) => {
const [filteredFG, setFilteredFG] = useState(
functionalGroups[FUNCTIONAL_GROUPS]
)
const [filteredSaltsAndSolvents, setFilteredSaltsAndSolvents] = useState(
saltsAndSolvents[SALTS_AND_SOLVENTS]
)

const filteredTemplateLib = filterLibSelector(props)

useEffect(() => {
setFilteredFG(filterFGLib(functionalGroups, filter)[FUNCTIONAL_GROUPS])
}, [functionalGroups, filter])

useEffect(() => {
setFilteredSaltsAndSolvents(filterFGLib(saltsAndSolvents, filter)[SALTS_AND_SOLVENTS])
}, [saltsAndSolvents, filter])

const handleTabChange = (_, tab) => {
setTab(tab)
props.onSelect(null)
Expand Down Expand Up @@ -189,10 +201,12 @@ const TemplateDialog: FC<Props> = (props) => {
}

const sdfSerializer = new SdfSerializer()
const data =
tab === TemplateTabs.TemplateLibrary
? sdfSerializer.serialize(templateLib)
: sdfSerializer.serialize(functionalGroups)
const serializerMapper = {
[TemplateTabs.TemplateLibrary]: templateLib,
[TemplateTabs.FunctionalGroupLibrary]: functionalGroups,
[TemplateTabs.SaltsAndSolvents]: saltsAndSolvents,
}
const data = sdfSerializer.serialize(serializerMapper[tab])

const select = (tmpl: Template, activateImmediately = false): void => {
onChangeGroup(tmpl.props.group)
Expand Down Expand Up @@ -231,6 +245,10 @@ const TemplateDialog: FC<Props> = (props) => {
label="Functional Groups"
{...a11yProps(TemplateTabs.FunctionalGroupLibrary)}
/>
<Tab
label="Salts and Solvents"
{...a11yProps(TemplateTabs.SaltsAndSolvents)}
/>
</Tabs>
<div className={classes.tabsContent}>
<TabPanel value={tab} index={TemplateTabs.TemplateLibrary}>
Expand Down Expand Up @@ -301,6 +319,23 @@ const TemplateDialog: FC<Props> = (props) => {
</div>
)}
</TabPanel>
<TabPanel value={tab} index={TemplateTabs.SaltsAndSolvents}>
{filteredSaltsAndSolvents?.length ? (
<div className={classes.resultsContainer}>
<TemplateTable
titleRows={1}
onDoubleClick={(templ) => select(templ, true)}
templates={filteredSaltsAndSolvents}
onSelect={(templ) => select(templ)}
selected={props.selected}
/>
</div>
) : (
<div className={classes.resultsContainer}>
<EmptySearchResult textInfo="No items found" />
</div>
)}
</TabPanel>
</div>
</Dialog>
)
Expand All @@ -314,7 +349,8 @@ export default connect(
const struct = template.struct.clone()
struct.sgroups.delete(0)
return { ...template, modifiedStruct: struct }
})
}),
saltsAndSolvents: saltsAndSolventsSelector(store)
}),
(dispatch: Dispatch<any>, props) => ({
onFilter: (filter) => dispatch(changeFilter(filter)),
Expand Down
2 changes: 2 additions & 0 deletions packages/ketcher-react/src/script/ui/state/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import templatesReducer, { initTmplsState } from './templates'

import actionStateReducer from './action'
import functionalGroupsReducer from './functionalGroups'
import saltsAndSolventsReducer from './saltsAndSolvents'
import { logger } from 'redux-logger'
import modalReducer from './modal'
import { pick } from 'lodash/fp'
Expand All @@ -39,6 +40,7 @@ const shared = combineReducers({
options: optionsReducer,
templates: templatesReducer,
functionalGroups: functionalGroupsReducer,
saltsAndSolvents: saltsAndSolventsReducer,
requestsStatuses: requestReducer
})

Expand Down
3 changes: 2 additions & 1 deletion packages/ketcher-react/src/script/ui/state/options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const initOptionsState = {
app: {
server: false,
templates: false,
functionalGroups: false
functionalGroups: false,
saltsAndSolvents: false,
},
analyse: {
values: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/****************************************************************************
* Copyright 2021 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/

import { AnyAction } from 'redux'
import { appUpdate } from '../options'
import {
SaltsAndSolventsProvider,
SdfItem,
SdfSerializer,
Struct
} from 'ketcher-core'
import { prefetchStatic } from '../templates/init-lib'

interface SaltsAndSolventsState {
lib: []
mode: string
}

const initialState: SaltsAndSolventsState = {
lib: [],
mode: 'saltsAndSolvents'
}

const saltsAndSolventsReducer = (
state = initialState,
{ type, payload }: AnyAction
) => {
switch (type) {
case 'SALTS_AND_SOLVENTS_INIT':
return { ...state, ...payload }

default:
return state
}
}

const initSaltsAndSolvents = (lib: SdfItem[]) => ({ type: 'SALTS_AND_SOLVENTS_INIT', payload: { lib } })

export function initSaltsAndSolventsTemplates(baseUrl: string) {
return async (dispatch) => {
const fileName = 'salts-and-solvents.sdf'
const url = `${baseUrl}/templates/${fileName}`
const provider = SaltsAndSolventsProvider.getInstance()
const sdfSerializer = new SdfSerializer()
const text = await prefetchStatic(url)
const templates = sdfSerializer.deserialize(text)
const saltsAndSolvents = templates.reduce(
(acc: Struct[], { struct }) => [...acc, struct],
[]
)
provider.setSaltsAndSolventsList(saltsAndSolvents)
dispatch(initSaltsAndSolvents(templates))
dispatch(appUpdate({ saltsAndSolvents: true }))
}
}

export default saltsAndSolventsReducer

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/****************************************************************************
* Copyright 2021 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/

export const saltsAndSolventsSelector = (state) => {
console.log('selector called ', state);
return state.saltsAndSolvents.lib
}

0 comments on commit a236295

Please sign in to comment.