| @@ -0,0 +1,152 @@ | |||
| import React from "react"; | |||
| import {Col, Row, Tree} from 'antd'; | |||
| const x = 3; | |||
| const y = 2; | |||
| const z = 1; | |||
| const defaultData = []; | |||
| const generateData = (_level, _preKey, _tns) => { | |||
| const preKey = _preKey || '0'; | |||
| const tns = _tns || defaultData; | |||
| const children = []; | |||
| for (let i = 0; i < x; i++) { | |||
| const key = `${preKey}-${i}`; | |||
| tns.push({ | |||
| title: key, | |||
| key, | |||
| }); | |||
| if (i < y) { | |||
| children.push(key); | |||
| } | |||
| } | |||
| if (_level < 0) { | |||
| return tns; | |||
| } | |||
| const level = _level - 1; | |||
| children.forEach((key, index) => { | |||
| tns[index].children = []; | |||
| return generateData(level, key, tns[index].children); | |||
| }); | |||
| }; | |||
| generateData(z); | |||
| class FoldTree extends React.Component { | |||
| constructor(props) { | |||
| super(props); | |||
| this.state = { | |||
| classes: props, | |||
| gData: defaultData, | |||
| expandedKeys: ['0-0', '0-0-0', '0-0-0-0'], | |||
| }; | |||
| } | |||
| updateTable(table) { | |||
| this.props.onUpdateTable(table); | |||
| } | |||
| renderTree(tree) { | |||
| const onDragEnter = (info) => { | |||
| console.log(info); // expandedKeys 需要受控时设置 | |||
| // setExpandedKeys(info.expandedKeys) | |||
| }; | |||
| const onDrop = (info) => { | |||
| console.log(info); | |||
| const dropKey = info.node.key; | |||
| const dragKey = info.dragNode.key; | |||
| const dropPos = info.node.pos.split('-'); | |||
| const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); | |||
| const loop = (data, key, callback) => { | |||
| for (let i = 0; i < data.length; i++) { | |||
| if (data[i].key === key) { | |||
| return callback(data[i], i, data); | |||
| } | |||
| if (data[i].children) { | |||
| loop(data[i].children, key, callback); | |||
| } | |||
| } | |||
| }; | |||
| const data = [...this.state.gData]; // Find dragObject | |||
| let dragObj; | |||
| loop(data, dragKey, (item, index, arr) => { | |||
| arr.splice(index, 1); | |||
| dragObj = item; | |||
| }); | |||
| if (!info.dropToGap) { | |||
| // Drop on the content | |||
| loop(data, dropKey, (item) => { | |||
| item.children = item.children || []; // where to insert 示例添加到头部,可以是随意位置 | |||
| item.children.unshift(dragObj); | |||
| }); | |||
| } else if ( | |||
| (info.node.props.children || []).length > 0 && // Has children | |||
| info.node.props.expanded && // Is expanded | |||
| dropPosition === 1 // On the bottom gap | |||
| ) { | |||
| loop(data, dropKey, (item) => { | |||
| item.children = item.children || []; // where to insert 示例添加到头部,可以是随意位置 | |||
| item.children.unshift(dragObj); // in previous version, we use item.children.push(dragObj) to insert the | |||
| // item to the tail of the children | |||
| }); | |||
| } else { | |||
| let ar = []; | |||
| let i; | |||
| loop(data, dropKey, (_item, index, arr) => { | |||
| ar = arr; | |||
| i = index; | |||
| }); | |||
| if (dropPosition === -1) { | |||
| ar.splice(i, 0, dragObj); | |||
| } else { | |||
| ar.splice(i + 1, 0, dragObj); | |||
| } | |||
| } | |||
| this.setState({ | |||
| gData: data, | |||
| }); | |||
| }; | |||
| return ( | |||
| <Tree | |||
| className="draggable-tree" | |||
| defaultExpandedKeys={this.state.expandedKeys} | |||
| draggable | |||
| blockNode | |||
| onDragEnter={onDragEnter} | |||
| onDrop={onDrop} | |||
| treeData={this.state.gData} | |||
| /> | |||
| ); | |||
| } | |||
| render() { | |||
| return ( | |||
| <div> | |||
| <Row style={{marginTop: '20px'}} > | |||
| <Col span={24}> | |||
| { | |||
| this.renderTree(this.props.tree) | |||
| } | |||
| </Col> | |||
| </Row> | |||
| </div> | |||
| ) | |||
| } | |||
| } | |||
| export default FoldTree; | |||
| @@ -1,11 +1,9 @@ | |||
| import React from "react"; | |||
| import {Button, Card, Col, Input, InputNumber, Row, Select} from 'antd'; | |||
| import {Button, Card, Col, Input, Row} from 'antd'; | |||
| import * as StoreBackend from "./backend/StoreBackend"; | |||
| import * as Setting from "./Setting"; | |||
| import i18next from "i18next"; | |||
| import VectorTable from "./VectorTable"; | |||
| const { Option } = Select; | |||
| import FolderTree from "./FolderTree"; | |||
| class StoreEditPage extends React.Component { | |||
| constructor(props) { | |||
| @@ -14,14 +12,11 @@ class StoreEditPage extends React.Component { | |||
| classes: props, | |||
| storeName: props.match.params.storeName, | |||
| store: null, | |||
| vectorsets: null, | |||
| matchLoading: false, | |||
| }; | |||
| } | |||
| componentWillMount() { | |||
| this.getStore(); | |||
| this.getVectorsets(); | |||
| } | |||
| getStore() { | |||
| @@ -80,37 +75,10 @@ class StoreEditPage extends React.Component { | |||
| </Row> | |||
| <Row style={{marginTop: '20px'}} > | |||
| <Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}> | |||
| {i18next.t("store:Vectorset")}: | |||
| </Col> | |||
| <Col span={22} > | |||
| <Select virtual={false} style={{width: '100%'}} value={this.state.store.vectorset} onChange={(value => {this.updateStoreField('vectorset', value);})}> | |||
| { | |||
| this.state.vectorsets?.map((vectorset, index) => <Option key={index} value={vectorset.name}>{vectorset.name}</Option>) | |||
| } | |||
| </Select> | |||
| </Col> | |||
| </Row> | |||
| <Row style={{marginTop: '20px'}} > | |||
| <Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}> | |||
| {i18next.t("store:Distance limit")}: | |||
| </Col> | |||
| <Col span={22} > | |||
| <InputNumber value={this.state.store.distanceLimit} onChange={value => { | |||
| this.updateStoreField('distanceLimit', value); | |||
| }} /> | |||
| </Col> | |||
| </Row> | |||
| <Row style={{marginTop: '20px'}} > | |||
| <Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}> | |||
| {i18next.t("store:Words")}: | |||
| {i18next.t("store:Folders")}: | |||
| </Col> | |||
| <Col span={22} > | |||
| <VectorTable | |||
| title={i18next.t("store:Words")} | |||
| table={this.state.store.vectors} | |||
| store={this.state.store} | |||
| onUpdateTable={(value) => { this.updateStoreField('vectors', value)}} | |||
| /> | |||
| <FolderTree tree={this.state.store.folders} /> | |||
| </Col> | |||
| </Row> | |||
| </Card> | |||
| @@ -34,7 +34,7 @@ class StoreListPage extends React.Component { | |||
| name: `store_${this.state.stores.length}`, | |||
| createdTime: moment().format(), | |||
| displayName: `Store ${this.state.stores.length}`, | |||
| children: [], | |||
| folders: [], | |||
| } | |||
| } | |||
| @@ -90,36 +90,6 @@ class StoreListPage extends React.Component { | |||
| width: '200px', | |||
| sorter: (a, b) => a.displayName.localeCompare(b.displayName), | |||
| }, | |||
| { | |||
| title: i18next.t("store:Words"), | |||
| dataIndex: 'vectors', | |||
| key: 'vectors', | |||
| // width: '120px', | |||
| sorter: (a, b) => a.vectors.localeCompare(b.vectors), | |||
| render: (text, record, index) => { | |||
| return Setting.getTags(text); | |||
| } | |||
| }, | |||
| // { | |||
| // title: i18next.t("store:All words"), | |||
| // dataIndex: 'allWords', | |||
| // key: 'allWords', | |||
| // width: '140px', | |||
| // sorter: (a, b) => a.allWords - b.allWords, | |||
| // render: (text, record, index) => { | |||
| // return record.vectors.length; | |||
| // } | |||
| // }, | |||
| // { | |||
| // title: i18next.t("store:Valid words"), | |||
| // dataIndex: 'validWords', | |||
| // key: 'validWords', | |||
| // width: '140px', | |||
| // sorter: (a, b) => a.validWords - b.validWords, | |||
| // render: (text, record, index) => { | |||
| // return record.vectors.filter(vector => vector.data.length !== 0).length; | |||
| // } | |||
| // }, | |||
| { | |||
| title: i18next.t("general:Action"), | |||
| dataIndex: 'action', | |||
| @@ -128,8 +98,7 @@ class StoreListPage extends React.Component { | |||
| render: (text, record, index) => { | |||
| return ( | |||
| <div> | |||
| <Button style={{marginTop: '10px', marginBottom: '10px', marginRight: '10px'}} onClick={() => Setting.openLink(`/stores/${record.name}/graph`)}>{i18next.t("general:Result")}</Button> | |||
| <Button style={{marginBottom: '10px', marginRight: '10px'}} onClick={() => Setting.downloadXlsx(record)}>{i18next.t("general:Download")}</Button> | |||
| <Button style={{marginTop: '10px', marginBottom: '10px', marginRight: '10px'}} onClick={() => this.props.history.push(`/stores/${record.name}/files`)}>{i18next.t("general:View")}</Button> | |||
| <Button style={{marginBottom: '10px', marginRight: '10px'}} type="primary" onClick={() => this.props.history.push(`/stores/${record.name}`)}>{i18next.t("general:Edit")}</Button> | |||
| <Popconfirm | |||
| title={`Sure to delete store: ${record.name} ?`} | |||