Chore: remove edit rule module

This commit is contained in:
Dreamacro 2018-12-08 23:29:14 +08:00
parent d38b75fb9a
commit 0c84cef257
4 changed files with 426 additions and 677 deletions

863
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,205 +1,36 @@
import * as React from 'react'
import produce from 'immer'
import { translate } from 'react-i18next'
import { SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc'
import { Header, Icon, Card, Row, Col, Select, Option, Input } from '@components'
import { I18nProps, RuleType, Rule, BaseRouterProps } from '@models'
import { Header, Card, Row, Col } from '@components'
import { I18nProps, BaseRouterProps } from '@models'
import './style.scss'
import { storeKeys } from '@lib/createStore'
import { inject } from 'mobx-react'
import { List, AutoSizer } from 'react-virtualized'
interface RulesProps extends BaseRouterProps, I18nProps {}
interface RulesState {
rules: Rule[]
proxies: { [key: string]: { type: string } }
modifiedIndex: number
}
@inject(...storeKeys)
class Rules extends React.Component<RulesProps, RulesState> {
state = {
rules: [
],
proxies: {
},
modifiedIndex: -1
}
class Rules extends React.Component<RulesProps, {}> {
async componentDidMount () {
const { config } = this.props
await config.fetchAndParseConfig()
const proxies = {
'REJECT': { type: 'Reject' },
'DIRECT': { type: 'Direct' }
}
config.config.proxy.map(p => proxies[p.name] = { type: p.type })
config.config.proxyGroup.map(p => proxies[p.name] = { type: p.type })
const rules = config.config.rules.filter(r => proxies[r.proxy])
this.setState({
rules,
proxies
})
}
private saveConfig = async () => {
const { config } = this.props
const { rules } = this.state
config.config.rules = rules
await config.updateConfig()
}
private handleModifyType = (index, type) => {
const { rules } = this.state
this.setState({
rules: produce(rules, draftState => {
draftState[index].type = type
})
}, () => {
this.saveConfig()
})
}
private handleModifyPayload = (index, payload) => {
const { rules } = this.state
this.setState({
rules: produce(rules, draftState => {
draftState[index].payload = payload
})
})
}
private handleModifyProxy = (index, proxy) => {
const { rules } = this.state
this.setState({
rules: produce(rules, draftState => {
draftState[index].proxy = proxy
})
}, () => {
this.saveConfig()
})
}
private addRule = () => {
const { rules } = this.state
const newRule = { type: RuleType['DOMAIN-SUFFIX'], payload: 'google.com.hk', proxy: 'DIRECT' }
const newRules = produce(rules, draftState => {
draftState.unshift(newRule)
})
this.setState({
rules: newRules,
modifiedIndex: 0
}, () => {
this.saveConfig()
})
}
private removeRule = (index) => {
const { rules } = this.state
this.setState({
rules: rules.filter((r, idx) => idx !== index)
}, () => {
this.saveConfig()
})
}
onSortEnd = ({ oldIndex, newIndex }) => {
this.setState({
rules: arrayMove(this.state.rules, oldIndex, newIndex)
})
}
renderRules = ({ rules }) => {
const SortableItem = SortableElement<{ rule: Rule, idx: number }>(itemProps => {
const { rule, idx } = itemProps
return this.renderRuleItem(rule, idx)
})
return <ul>
{
rules.map((rule: Rule, idx: number) => {
const isFinal = rule.type === 'FINAL'
return <SortableItem key={idx} index={idx} idx={idx} rule={rule} disabled={isFinal} />
})
}
</ul>
}
renderRuleItem = (rule: Rule, index) => {
const { modifiedIndex, proxies } = this.state
const isFinal = rule.type === 'FINAL'
const DragHandle = SortableHandle(() => <Icon type="drag" size={16} />)
renderRuleItem = ({ index, key, style }) => {
const { rules } = this.props.config.config
const rule = rules[index]
return (
<li className="rule-item" key={index}>
<li className="rule-item" key={key} style={style}>
<Row className="rule-item-row" gutter={24} align="middle">
<Col className="drag-handler" span={1}>
{!isFinal && <DragHandle />}
<Col className="rule-type" span={6} offset={1}>
{ rule.type }
</Col>
<Col className="rule-type" span={5}>
{
isFinal
? rule.type
: (
<Select
key={index}
value={rule.type}
onSelect={type => this.handleModifyType(index, type)}
style={{ flex: 1 }}
>
{
Object.keys(RuleType)
.filter(type => type !== 'FINAL')
.map(typeName => {
const type = RuleType[typeName]
return (
<Option value={type} key={type}>{type}</Option>
)
})
}
</Select>
)
}
<Col className="payload" span={11}>
{ rule.payload }
</Col>
<Col className="payload" span={8}>
{
modifiedIndex === index
? (
<Input
value={rule.payload}
align="left"
inside={true}
autoFocus={true}
onChange={ value => this.handleModifyPayload(index, value) }
onBlur={() => { this.setState({ modifiedIndex: -1 });this.saveConfig() }}
style={{ maxWidth: 230 }}
/>
)
: <span onClick={() => this.setState({
modifiedIndex: index
})}>{rule.payload}</span>
}
</Col>
<Col className="rule-proxy" span={5}>
<Select className="rule-proxy-option" key={index} value={rule.proxy} onSelect={proxy => this.handleModifyProxy(index, proxy)}>
{
Object.keys(proxies).map(proxyName => {
const proxy = proxies[proxyName]
return (
<Option className="rule-proxy-option" value={proxyName} key={`${proxyName}-${proxy.type}`}>
<span className="label">{proxy.type}</span>
<span className="value">{proxyName}</span>
</Option>
)
})
}
</Select>
</Col>
<Col className="delete-btn" span={2} offset={3}>
{!isFinal && <span onClick={() => this.removeRule(index)}></span>}
<Col className="rule-proxy" span={6}>
{ rule.proxy }
</Col>
</Row>
</li>
@ -208,21 +39,25 @@ class Rules extends React.Component<RulesProps, RulesState> {
render () {
const { t } = this.props
const { rules } = this.state
// const SortableList = SortableContainer<{ rules: Rule[] }>(this.renderRules)
const { rules } = this.props.config.config
return (
<div className="page">
<Header title={t('title')} >
<Icon type="plus" size={20} style={{ fontWeight: 'bold', cursor: 'pointer' }} onClick={this.addRule}/>
</Header>
<Header title={t('title')} />
<Card className="rules-card">
<div className="rules">
<AutoSizer className="rules">
{
rules.map((rule: Rule, index) => this.renderRuleItem(rule, index))
({ height, width }) => (
<List
height={height}
width={width}
rowCount={rules.length}
rowRenderer={this.renderRuleItem}
rowHeight={50}
overscanRowCount={10}
/>
)
}
{/* <SortableList rules={rules} onSortEnd={this.onSortEnd} useDragHandle={true} /> */}
</div>
</AutoSizer>
</Card>
</div>
)

View File

@ -7,19 +7,20 @@
margin-top: 10px;
padding: 0;
&:focus {
outline: none;
}
.rules {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-basis: 0;
overflow-y: auto;
overflow-x: hidden;
flex: 1 0 auto;
}
}
.rule-item {
line-height: 30px;
padding: 5px 0;
height: 50px;
overflow: hidden;
list-style: none;
user-select: none;
border-bottom: 1px solid rgba($color: $color-primary-lightly, $alpha: 0.5);

View File

@ -8,7 +8,11 @@ import { getLocalStorageItem } from '@lib/helper'
export class ConfigStore {
@observable
config: Models.Config = {}
config: Models.Config = {
proxy: [],
proxyGroup: [],
rules: []
}
@observable
public state: 'pending' | 'ok' | 'error' = 'pending'