UNPKG

anyproxy

Version:

A fully configurable HTTP/HTTPS proxy in Node.js

253 lines (219 loc) 7.89 kB
/** * The panel map request to local * */ import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; import { Tree, Form, Input, Button } from 'antd'; import ResizablePanel from 'component/resizable-panel'; import PromiseUtil from 'common/promiseUtil'; import { fetchDirectory, hideMapLocal, fetchMappedConfig, updateRemoteMappedConfig } from 'action/globalStatusAction'; import { MenuKeyMap } from 'common/constant'; import Style from './map-local.less'; import CommonStyle from '../style/common.less'; const TreeNode = Tree.TreeNode; const createForm = Form.create; const FormItem = Form.Item; class MapLocal extends React.Component { constructor () { super(); this.state = { selectedLocalPath: '' }; this.loadTreeNode = this.loadTreeNode.bind(this); this.onClose = this.onClose.bind(this); this.getFormDiv = this.getFormDiv.bind(this); this.onNodeSelect = this.onNodeSelect.bind(this); this.getMappedConfigDiv = this.getMappedConfigDiv.bind(this); this.loadMappedConfig = this.loadMappedConfig.bind(this); this.addMappedConfig = this.addMappedConfig.bind(this); this.removeMappedConfig = this.removeMappedConfig.bind(this); } static propTypes = { dispatch: PropTypes.func, globalStatus: PropTypes.object, form: PropTypes.object } loadTreeNode(node) { const d = PromiseUtil.defer(); const key = node ? node.props.eventKey : ''; this.props.dispatch(fetchDirectory(key)); setTimeout(function() { d.resolve(); }, 500); return d.promise; } loadMappedConfig() { this.props.dispatch(fetchMappedConfig()); } addMappedConfig () { const config = this.props.globalStatus.mappedConfig.slice(); this.props.form.validateFieldsAndScroll((error, value) => { config.push({ keyword: value.keyword, local: value.local }); this.props.dispatch(updateRemoteMappedConfig(config)); }); } removeMappedConfig (index) { const config = this.props.globalStatus.mappedConfig.slice(); config.splice(index, 1); this.props.dispatch(updateRemoteMappedConfig(config)); } loopTreeNode(nodes) { const treeNodes = nodes.map((item) => { if (item.children) { return ( <TreeNode title={item.name} key={item.fullPath}> {this.loopTreeNode(item.children)} </TreeNode> ); } else { return <TreeNode title={item.name} key={item.fullPath} isLeaf={item.isLeaf} />; } }); return treeNodes; } onClose () { this.props.dispatch(hideMapLocal()); } onNodeSelect (selectedKeys, { selected, selectedNodes }) { const node = selectedNodes[0]; // Only a file will be mapped if (node && node.props.isLeaf) { this.setState({ selectedLocalPath: selectedKeys[0] }); } } getFormDiv () { const { getFieldDecorator, getFieldError } = this.props.form; const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 18 }, }; const keywordProps = getFieldDecorator('keyword', { initialValue: '', validate: [ { trigger: 'onBlur', rules: [ { type: 'string', whitespace: true, required: true, message: '请录入需要映射的url匹配' } ] } ] }); const localProps = getFieldDecorator('local', { initialValue: this.state.selectedLocalPath, validate: [ { trigger: 'onBlur', rules: [ { type: 'string', whitespace: true, required: true, message: '请输入本地文件路径' } ] } ] }); return ( <div className={Style.form} > <Form vertical > <FormItem label="Keyword" > {keywordProps(<Input placeholder="The pattern to map" />)} </FormItem> <FormItem label="Local file" > {localProps(<Input placeholder="Local file for the mapped url" />)} </FormItem> </Form> </div> ); } getMappedConfigDiv () { const { mappedConfig } = this.props.globalStatus; const mappedLiDiv = mappedConfig.map((item, index) => { return ( <li key={index} > <div> <div className={Style.mappedKeyDiv} > <strong>{item.keyword}</strong> <a href="javascript:void(0)" onClick={this.removeMappedConfig.bind(this, index)} > Remove </a> </div> <div className={Style.mappedLocal} > {item.local} </div> </div> </li> ); }); return ( <div className={Style.mappedConfigWrapper} > <div > <span className={CommonStyle.sectionTitle}>Current Configuration</span> </div> <div className={CommonStyle.whiteSpace10} /> <ul className={Style.mappedList} > {mappedLiDiv} </ul> </div> ); } componentDidMount () { this.loadTreeNode(); this.loadMappedConfig(); } render() { const treeNodes = this.loopTreeNode(this.props.globalStatus.directory); const panelVisible = this.props.globalStatus.activeMenuKey === MenuKeyMap.MAP_LOCAL; return ( <ResizablePanel onClose={this.onClose} visible={panelVisible} > <div className={Style.mapLocalWrapper} > <div className={Style.title} > Map Local </div> {this.getMappedConfigDiv()} <div > <span className={CommonStyle.sectionTitle}>Add Local Map</span> </div> <div className={CommonStyle.whiteSpace10} /> {this.getFormDiv()} <div className={Style.treeWrapper} > <Tree loadData={this.loadTreeNode} onSelect={this.onNodeSelect} > {treeNodes} </Tree> </div> <div className={Style.operations} > <Button type="primary" onClick={this.addMappedConfig} >Add</Button> </div> </div> </ResizablePanel> ); } } function select (state) { return { globalStatus: state.globalStatus }; } export default connect(select)(createForm()(MapLocal));