diff --git a/web/src/components/infini/InputSelect.js b/web/src/components/infini/InputSelect.js index db1b1d3c..8d9e1cc4 100644 --- a/web/src/components/infini/InputSelect.js +++ b/web/src/components/infini/InputSelect.js @@ -9,7 +9,6 @@ class InputSelect extends React.Component{ super(props); this.state = { value: props.defaultValue || props.value, - originData: props.data || [], } } @@ -27,7 +26,7 @@ class InputSelect extends React.Component{ } handleChange = (ev) => { let val = ev.target.value; - let filterData = this.state.originData.slice(); + let filterData = this.props.data.slice(); if(val != ""){ filterData = filterData.filter(v=>v.value.includes(val)) } diff --git a/web/src/pages/DataManagement/Document.js b/web/src/pages/DataManagement/Document.js index e5446f92..967d6447 100644 --- a/web/src/pages/DataManagement/Document.js +++ b/web/src/pages/DataManagement/Document.js @@ -2,13 +2,16 @@ import React from 'react'; import { formatMessage, FormattedMessage } from 'umi/locale'; import router from 'umi/router'; import { connect } from 'dva'; -import { Col, Form, Row,Select, Input, Card,Icon, Table, InputNumber, Popconfirm, - Divider,Button,Tooltip, Modal, DatePicker, message,Cascader } from 'antd'; +import { + Col, Form, Row, Select, Input, Card, Icon, Table, InputNumber, Popconfirm, + Divider, Button, Tooltip, Modal, DatePicker, message, Cascader, List,Radio +} from 'antd'; import Editor, {monaco} from '@monaco-editor/react'; import moment from 'moment'; import {createDependencyProposals} from './autocomplete'; import InputSelect from '@/components/infini/InputSelect'; import {getFields,getESAPI} from '@/lib/elasticsearch/util'; +import {Link} from "_umi@2.13.16@umi"; function findParentIdentifier(textUntilPosition){ let chars = textUntilPosition; @@ -99,7 +102,184 @@ function initEditor() { }) } -const {Option} = Select; +class EditModal extends React.Component{ + okHandle = () => { + const {handleUpdate, values} = this.props; + handleUpdate({ + _type: values._type, + _index: values._index, + _id: values.id, + data: JSON.parse(this.valueGetter()), + }); + } + handleEditorDidMount = (valueGetter)=>{ + this.valueGetter = valueGetter; + } + render(){ + const { handleModalVisible, values, cleanRecord } = this.props; + let newR = cleanRecord(values); + return ( + handleModalVisible()} + > +
+ +
+
+ ); + } +} + +class JSONTable extends React.Component{ + handleTableChange = (page, size) =>{ + //console.log(pagination, filters, sorter); + + const {fetchData, doclist} = this.props; + fetchData({ + pageIndex: page, + pageSize: size || doclist.pageSize, + index: doclist.index, + cluster: doclist.cluster, + filter: doclist.filter, + }) + } + setStateValue = (payload) =>{ + const {dispatch} = this.props; + dispatch({ + type: 'document/saveData', + payload: { + ...payload, + } + }) + } + handleEditClick = (record)=>{ + this.setStateValue({ + editValue: record + }); + } + handleModalVisible =()=>{ + const {doclist} = this.props; + let payload = { + editValue: null, + }; + if(doclist.isAddNew){ + payload.isAddNew = false; + } + this.setStateValue(payload); + } + handleDeleteClick = (record)=>{ + const {dispatch} = this.props; + dispatch({ + type: 'document/deleteDocItem', + payload: { + _id: record.id, + _index: record._index, + _type: record._type, + }, + }) + } + handleSaveItemClick = (values)=>{ + const {dispatch, doclist} = this.props; + if(doclist.isAddNew){ + dispatch({ + type: 'document/addDocItem', + payload: values, + }); + }else { + dispatch({ + type: 'document/saveDocItem', + payload: values, + }); + } + } + cleanRecord = (record)=>{ + let newR = { + ...record + }; + delete(newR["_type"]); + delete(newR["_index"]); + delete(newR["id"]); + return newR; + } + render() { + let {data, total, pageSize,pageIndex, resultKey, editValue} = this.props.doclist; + if(total && total.value){ + total = total.value; + } + let dataList = _.clone(data) || []; + dataList = dataList.filter(item=>{ + return item._index === resultKey; + }) + return( +
+ {editValue ? : null} + { + this.handleTableChange(page, size); + }, + onShowSizeChange: (current, size)=>{ + this.handleTableChange(current, size); + }, + total: total, + showSizeChanger: true, + pageSizeOptions: ["3","6","10","20"], + pageSize: pageSize || 10, + current: pageIndex || 1, + showTotal: (total, range) => `Total ${total} items`, + size: 'small', + }} + renderItem={item => ( + + this.handleEditClick(item)} />, + this.handleDeleteClick(item)}> + + , + ]}> +
+
{JSON.stringify(this.cleanRecord(item), null, 2)}
+
+
+
+ )} + /> +
+ ) + } +} const EditableContext = React.createContext(); @@ -128,12 +308,10 @@ class EditableCell extends React.Component { type, ...restProps } = this.props; - let initialValue = ''; + let initialValue = (record && record[dataIndex]) || ''; if(editing){ if(type=='date'){ initialValue = record[dataIndex] && moment(record[dataIndex]); - }else{ - initialValue = record[dataIndex]; } } return ( @@ -250,19 +428,17 @@ class EditableCell extends React.Component { dispatch({ type: 'document/saveDocItem', payload: { - index: doclist._index, + _index: doclist._index, _type: doclist._type, - data: { - id: key, - ...row, - } + _id: key, + data: row, } }) }else{ dispatch({ type: 'document/addDocItem', payload: { - index: doclist._index, + _index: doclist._index, _type: doclist._type, data: row, } @@ -284,11 +460,9 @@ class EditableCell extends React.Component { dispatch({ type: 'document/deleteDocItem', payload: { - index: record._index, + _index: record._index, _type: record._type, - data: { - id: record.id, - } + _id: record.id, } }); } @@ -318,7 +492,11 @@ class EditableCell extends React.Component { let keys = []; let sortObj = {}; if(doclist.mappings){ - keys = getFields(doclist.index, doclist.mappings) + let index = doclist.index; + if(!doclist.data || doclist.data.length === 0 || (doclist.data.length===1 &&doclist.data[0].id==="" )){ + index = doclist.resultKey; + } + keys = getFields(index, doclist.mappings) } for(let key of keys){ if(["_index"].includes(key)){ @@ -358,6 +536,10 @@ class EditableCell extends React.Component { if(total.value){ total = total.value; } + let data = _.clone(doclist.data) || []; + data = data.filter(item=>{ + return item._index === doclist.resultKey; + }) return ( { @@ -514,7 +708,7 @@ class Doucment extends React.Component { message.error('please select cluster and index'); return; } - if(this.state.bodyDisplay != 'none'){ + if(this.state.bodyDisplay !== 'none'){ filter = this.filterGetter(); } this.fetchData({ @@ -533,9 +727,18 @@ class Doucment extends React.Component { }) } + handleTableModeChange = (e)=> { + const {dispatch} = this.props; + dispatch({ + type: 'document/saveData', + payload: { + tableMode: e.target.value, + } + }); + } renderNew = ()=>{ - let {indices, mappings} = this.props.document; + let {indices, mappings, resultKey, tableMode} = this.props.document; // if((indices && indices.length > 1)){ // return; // } @@ -562,13 +765,10 @@ class Doucment extends React.Component { } return newItem; }); - this.indexSelEl && this.indexSelEl.setState({ - value: [indices[0].value] - }) } return (
- {(indices && indices.length>0) ? ({this.indexSelEl=el}} defaultValue={[indices[0].value]} options={indices} style={{width: 200, marginRight:5}} placeholder="please select a index"> + {(indices && indices.length>0) ? ({this.indexSelEl=el}} onChange={(vals)=>{this.handleResultTabKeyChange(vals[0])}} value={[resultKey]} options={indices} style={{width: 200, marginRight:5}} placeholder="please select a index"> ) : ''} {/*{(indices) ? () : ''}*/} + + {/*Select Viewer: */} + + TABLE + JSON + +
) } + handleResultTabKeyChange=(key)=>{ + const {dispatch} = this.props; + dispatch({ + type:'document/saveData', + payload:{ + resultKey: key, + } + }) + } render(){ // const {getFieldDecorator} = this.props.form; @@ -592,9 +808,17 @@ class Doucment extends React.Component { }; }) const clusters = ["single-es"]; - let {cluster, index}= this.props.document; + let {cluster, index, indices, tableMode}= this.props.document; cluster = cluster || this.props.location.query.cluster || 'single-es'; index = index || this.props.location.query.index; + indices = indices || []; + + let resultTabList = indices.map(item=>{ + return { + key: item, + tab: item, + } + }); return (
@@ -608,10 +832,10 @@ class Doucment extends React.Component { {this.hashChanged=true;}} defaultValue={index} ref={el=>{this.indexEl=el}} placeholder="input index or index pattern" style={{width: '25%'}}/> this.keywordEl=el} - placeholder="input search keyword" - disabled = {this.state.bodyDisplay != 'none'} + placeholder="input search keyword" + // disabled={this.state.bodyDisplay != 'none'} /> @@ -619,17 +843,21 @@ class Doucment extends React.Component {
{ this.setState((preState)=>{ - if(preState.bodyDisplay == 'none') { + if(preState.bodyDisplay === 'none') { + initEditor(); return { bodyDisplay: 'block', }; }else{ + if(langDisposer != null) { + langDisposer.dispose(); + } return { bodyDisplay: 'none' }; } }); - }}>{this.state.bodyDisplay == 'none' ? formatMessage({id:'form.button.advanced'}): formatMessage({id:'form.button.collapse'})} + }}>{this.state.bodyDisplay === 'none' ? formatMessage({id:'form.button.advanced'}): formatMessage({id:'form.button.collapse'})} @@ -670,9 +898,16 @@ class Doucment extends React.Component { - {this.fetchData(params)}}/> + {tableMode !== 'JSON' ? + { + this.fetchData(params) + }}/> : + {this.fetchData(params)}} /> + } diff --git a/web/src/pages/DataManagement/models/document.js b/web/src/pages/DataManagement/models/document.js index 0db29ffa..079b1947 100644 --- a/web/src/pages/DataManagement/models/document.js +++ b/web/src/pages/DataManagement/models/document.js @@ -2,14 +2,15 @@ import {getDocList, saveDoc, deleteDoc, addDoc} from '@/services/doc'; import {getMappings, getIndices} from '@/services/indices'; import {formatESSearchResult} from '@/lib/elasticsearch/util'; import { message } from 'antd'; +import moment from "moment"; function encodeObjectField(doc){ - //let rawData = {}; for(let key of Object.keys(doc)){ if(typeof doc[key] == 'object'){ - // let docId = doc['id']; - // !rawData[docId] && (rawData[docId] = {}); - // rawData[docId][key] = doc[key]; + if(doc[key] instanceof moment){ + doc[key] = doc[key].toJSON(); + continue; + } doc[key] = JSON.stringify(doc[key]); } } @@ -18,6 +19,9 @@ function encodeObjectField(doc){ function decodeObjectField(doc){ for(let key of Object.keys(doc)){ + if(!doc[key]){ + continue; + } if(['[', '{'].includes(doc[key][0])){ try{ doc[key] = JSON.parse(doc[key]) @@ -36,9 +40,11 @@ export default { index: '', editingKey: '', isLoading: false, + resultKey: '', + tableMode: 'JSON', }, effects: { - *fetchDocList({payload}, {call, put}){ + *fetchDocList({payload}, {call, put, select}){ yield put({ type: 'saveData', payload: { @@ -56,6 +62,7 @@ export default { }) return } + const {tableMode} = yield select(state=>state.document); res.payload = formatESSearchResult(res.payload); let indices = []; //indices state can remove if(res.payload.data && res.payload.data.length > 0){ @@ -63,7 +70,9 @@ export default { if(!indices.includes(doc._index)){ indices.push(doc._index); } - encodeObjectField(doc); + if(tableMode !== "JSON") { + encodeObjectField(doc); + } } } yield put({ @@ -74,6 +83,7 @@ export default { isLoading: false, index: payload.index, indices, + resultKey: indices[0] || '', cluster: payload.cluster || '', filter: payload.filter || '', ...res.payload, @@ -89,8 +99,11 @@ export default { }); let doc = payload.data; //let {rawData} = yield select(state => state.document); - if(decodeObjectField(doc) === false){ - return; + const {tableMode} = yield select(state=>state.document); + if(tableMode !== 'JSON') { + if (decodeObjectField(doc) === false) { + return; + } } let res = yield call(saveDoc, payload); if(res.status === false){ @@ -105,18 +118,24 @@ export default { }) return } - encodeObjectField(doc); + if(tableMode !== 'JSON') { + encodeObjectField(doc); + } + //console.log(payload.data); yield put({ type: '_saveDocItem', payload: { docItem: payload.data, + id: payload._id, extra: { editingKey: '', isLoading: false, + editValue: null, _index: '' } } - }) + }); + message.success("保存数据成功"); }, *deleteDocItem({payload}, {call, put}){ yield put({ @@ -136,30 +155,36 @@ export default { yield put({ type: '_deleteDocItem', payload: { - docItem: payload.data, + id: payload._id, extra: { isLoading: false, } } }) + message.success("删除数据成功") }, - *addDocItem({payload},{call, put}){ + *addDocItem({payload},{call, put, select}) { yield put({ type: 'saveData', payload: { isLoading: true, } }); - if(decodeObjectField(payload.data) === false){ - return; + const {tableMode} = yield select(state => state.document); + if (tableMode !== 'JSON') { + if (decodeObjectField(payload.data) === false) { + return; + } } let res = yield call(addDoc, payload); - if(res.status === false){ + if (res.status === false) { message.warn("添加文档失败") return } - encodeObjectField(res.payload); - res.payload['_index'] = payload.index; + if (tableMode !== 'JSON') { + encodeObjectField(res.payload); + } + res.payload['_index'] = payload._index; res.payload['_type'] = payload._type; yield put({ type: '_addNew', @@ -168,9 +193,11 @@ export default { extra: { isLoading: false, isAddNew: false, + editValue: null, } } - }) + }); + message.success("添加文档成功") }, *fetchIndices({payload}, {call, put}){ let resp = yield call(getIndices) @@ -209,7 +236,7 @@ export default { }, _saveDocItem(state, {payload}){ let idx = state.data.findIndex((item) => { - return item.id == payload.docItem.id; + return item.id === payload.id; }); idx > -1 && (state.data[idx] = { ...state.data[idx], @@ -223,7 +250,7 @@ export default { }, _deleteDocItem(state, {payload}){ let idx = state.data.findIndex((item) => { - return item.id == payload.docItem.id; + return item.id === payload.id; }); state.data.splice(idx, 1); return { @@ -237,16 +264,19 @@ export default { }, _addNew(state, {payload}){ if(payload.extra && payload.extra.isAddNew){ - if(!state.data){ - state.data = []; - } - state.data.unshift(payload.docItem) + let data = state.data || []; + data.unshift(payload.docItem); return { ...state, + data: data, ...payload.extra, } }else{ - state.data[0] = payload.docItem; + if(state.tableMode !=='JSON') { + state.data[0] = payload.docItem; + }else{ + state.data.unshift(payload.docItem); + } return { ...state, ...payload.extra, diff --git a/web/src/services/doc.js b/web/src/services/doc.js index a3cd2166..fdc9192f 100644 --- a/web/src/services/doc.js +++ b/web/src/services/doc.js @@ -13,7 +13,7 @@ export async function getDocList(params) { } export async function saveDoc(params) { - let url = `${pathPrefix}/doc/${params.index}/${params.data.id}`; + let url = `${pathPrefix}/doc/${params._index}/${params._id}`; if(params._type){ url += `?_type=${params._type}`; } @@ -24,7 +24,7 @@ export async function saveDoc(params) { } export async function deleteDoc(params) { - let url =`${pathPrefix}/doc/${params.index}/${params.data.id}`; + let url =`${pathPrefix}/doc/${params._index}/${params._id}`; if(params._type){ url += `?_type=${params._type}`; } @@ -34,9 +34,7 @@ export async function deleteDoc(params) { } export async function addDoc(params) { - let id = params.data.id || ''; - delete(params.data, 'id'); - let url = `${pathPrefix}/doc/${params.index}/_create`; + let url = `${pathPrefix}/doc/${params._index}/_create`; if(params._type){ url += `?_type=${params._type}`; }