/**************************************************************************** * Copyright 2017 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 { escapeRegExp, chunk, flow, filter as _filter, reduce, omit } from 'lodash/fp'; import { createSelector } from 'reselect'; import { h, Component } from 'preact'; import { connect } from 'preact-redux'; /** @jsx h */ import sdf from '../../chem/sdf'; import VisibleView from '../component/visibleview'; import StructRender from '../component/structrender'; import Dialog from '../component/dialog'; import SaveButton from '../component/savebutton'; import Input from '../component/input'; import SelectList from '../component/select'; import { changeFilter, changeGroup, selectTmpl, editTmpl } from '../state/templates'; import { onAction } from "../state/"; const GREEK_SIMBOLS = { 'Alpha': 'A', 'alpha': 'α', 'Beta': 'B', 'beta': 'β', 'Gamma': 'Г', 'gamma': 'γ' }; function tmplName(tmpl, i) { console.assert(tmpl.props && tmpl.props.group, "No group"); return tmpl.struct.name || `${tmpl.props.group} template ${i + 1}`; } function partition(n, array) { console.warn('partition', n); return chunk(n)(array); } const greekRe = new RegExp('\\b' + Object.keys(GREEK_SIMBOLS).join('\\b|\\b') + '\\b', 'g'); function greekify(str) { return str.replace(greekRe, sym => GREEK_SIMBOLS[sym]); } const filterLibSelector = createSelector( (props) => props.lib, (props) => props.filter, filterLib ); function filterLib(lib, filter) { console.warn('Filter', filter); let re = new RegExp(escapeRegExp(greekify(filter)), 'i'); return flow( _filter(item => !filter || re.test(greekify(item.struct.name)) || re.test(greekify(item.props.group))), reduce((res, item) => { !res[item.props.group] ? res[item.props.group] = [item] : res[item.props.group].push(item); return res; }, {}) )(lib) } const libRowsSelector = createSelector( (props) => props.lib, (props) => props.group, (props) => props.COLS, libRows ); function libRows(lib, group, COLS) { console.warn("Group", group); return partition(COLS, lib[group]) } function RenderTmpl({ tmpl, ...props }) { return tmpl.props && tmpl.props.prerender ? ( ) : ( ); } class TemplateLib extends Component { select(tmpl) { if (tmpl === this.props.selected) this.props.onOk(this.result()); else this.props.onSelect(tmpl); } result() { const tmpl = this.props.selected; console.assert(!tmpl || tmpl.props, 'Incorrect SDF parse'); return tmpl ? { struct: tmpl.struct, aid: parseInt(tmpl.props.atomid) || null, bid: parseInt(tmpl.props.bondid) || null } : null; } renderRow(row, index, COLS) { return (
{ row.map((tmpl, i) => (
this.select(tmpl)}/>
))}
); } render() { const COLS = 3; let { group, filter, onFilter, onChangeGroup, ...props } = this.props; const lib = filterLibSelector(this.props); group = lib[group] ? group : Object.keys(lib)[0]; return ( this.result()} buttons={[ Save To SDF… , "OK", "Cancel"]}> onChangeGroup(g)} schema={{ enum: Object.keys(lib), enumNames: Object.keys(lib).map(g => greekify(g)) }}/> { (row, i) => this.renderRow(row, i, COLS) } ); } } export default connect( store => ({ ...omit(['attach'], store.templates) }), (dispatch, props) => ({ onFilter: filter => dispatch(changeFilter(filter)), onSelect: tmpl => dispatch(selectTmpl(tmpl)), onChangeGroup: group => dispatch(changeGroup(group)), onAttach: tmpl => dispatch(editTmpl(tmpl)), onOk: res => { dispatch(onAction({ tool: 'template', opts: res })); props.onOk(res); } }) )(TemplateLib);