fullfill document CURD preview
This commit is contained in:
parent
814405709f
commit
a74511ad4d
|
@ -0,0 +1,136 @@
|
||||||
|
package index_management
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
httprouter "infini.sh/framework/core/api/router"
|
||||||
|
"infini.sh/framework/core/elastic"
|
||||||
|
"infini.sh/framework/core/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type docReqBody struct {
|
||||||
|
Index string `json:"index"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
Payload map[string]interface{} `json:"payload"`
|
||||||
|
PageIndex int `json:"pageIndex"`
|
||||||
|
PageSize int `json:"pageSize"`
|
||||||
|
Filter string `json:"filter"`
|
||||||
|
Cluster string `json:"cluster"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler APIHandler) HandleDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||||
|
reqBody := docReqBody{}
|
||||||
|
resResult := map[string]interface{}{
|
||||||
|
"errno": "0",
|
||||||
|
"errmsg": "",
|
||||||
|
"payload": nil,
|
||||||
|
}
|
||||||
|
err := handler.DecodeJSON(req, &reqBody)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
indexName := ps.ByName("index")
|
||||||
|
var id string
|
||||||
|
if val, ok := reqBody.Payload["id"]; ok {
|
||||||
|
id = val.(string)
|
||||||
|
}
|
||||||
|
if _, ok := reqBody.Payload["_index"]; ok {
|
||||||
|
delete(reqBody.Payload, "_index")
|
||||||
|
}
|
||||||
|
switch reqBody.Action {
|
||||||
|
case "ADD":
|
||||||
|
id = util.GetUUID()
|
||||||
|
//security problem
|
||||||
|
_, err := client.Index(indexName, id, reqBody.Payload)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
reqBody.Payload["id"] = id
|
||||||
|
resResult["payload"] = reqBody.Payload
|
||||||
|
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||||
|
case "SAVE":
|
||||||
|
if id == "" {
|
||||||
|
panic("empty id")
|
||||||
|
}
|
||||||
|
resp, err := client.Get(indexName, id)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
source := resp.Source
|
||||||
|
for k, v := range reqBody.Payload {
|
||||||
|
source[k] = v
|
||||||
|
}
|
||||||
|
_, err = client.Index(indexName, id, source)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||||
|
|
||||||
|
case "DELETE":
|
||||||
|
if id == "" {
|
||||||
|
panic("empty id")
|
||||||
|
}
|
||||||
|
_, err = client.Delete(indexName, id)
|
||||||
|
if err != nil {
|
||||||
|
resResult["errmsg"] = err.Error()
|
||||||
|
resResult["errno"] = "E100003"
|
||||||
|
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||||
|
default:
|
||||||
|
var (
|
||||||
|
pageSize = 10
|
||||||
|
pageIndex = 1
|
||||||
|
)
|
||||||
|
if reqBody.PageSize > 0 {
|
||||||
|
pageSize = reqBody.PageSize
|
||||||
|
}
|
||||||
|
if reqBody.PageIndex > 0 {
|
||||||
|
pageIndex = reqBody.PageIndex
|
||||||
|
}
|
||||||
|
from := (pageIndex - 1) * pageSize
|
||||||
|
filter := `{"match_all": {}}`
|
||||||
|
if reqBody.Filter != "" {
|
||||||
|
filter = reqBody.Filter
|
||||||
|
}
|
||||||
|
query := fmt.Sprintf(`{"from":%d, "size": %d, "query": %s}`, from, pageSize, filter)
|
||||||
|
var reqBytes = []byte(query)
|
||||||
|
resp, err := client.SearchWithRawQueryDSL(indexName, reqBytes)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := formatESSearchResult(resp)
|
||||||
|
|
||||||
|
handler.WriteJSON(w, map[string]interface{}{
|
||||||
|
"errno": "0",
|
||||||
|
"errmsg": "",
|
||||||
|
"payload": result,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatESSearchResult(esResp *elastic.SearchResponse) map[string]interface{} {
|
||||||
|
total := esResp.Hits.Total
|
||||||
|
if len(esResp.Hits.Hits) == 0 {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"total": total,
|
||||||
|
"data": nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataArr := make([]interface{}, 0, len(esResp.Hits.Hits))
|
||||||
|
for _, hit := range esResp.Hits.Hits {
|
||||||
|
if _, ok := hit.Source["id"]; !ok {
|
||||||
|
hit.Source["id"] = hit.ID
|
||||||
|
}
|
||||||
|
hit.Source["_index"] = hit.Index
|
||||||
|
dataArr = append(dataArr, hit.Source)
|
||||||
|
}
|
||||||
|
return map[string]interface{}{
|
||||||
|
"total": total,
|
||||||
|
"data": dataArr,
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,10 +10,12 @@ import (
|
||||||
httprouter "infini.sh/framework/core/api/router"
|
httprouter "infini.sh/framework/core/api/router"
|
||||||
"infini.sh/framework/core/orm"
|
"infini.sh/framework/core/orm"
|
||||||
"infini.sh/framework/core/util"
|
"infini.sh/framework/core/util"
|
||||||
|
"infini.sh/search-center/config"
|
||||||
model2 "infini.sh/search-center/model"
|
model2 "infini.sh/search-center/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIHandler struct {
|
type APIHandler struct {
|
||||||
|
Config *config.AppConfig
|
||||||
api.Handler
|
api.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,37 +46,22 @@ func (handler APIHandler) GetDictListAction(w http.ResponseWriter, req *http.Req
|
||||||
|
|
||||||
func (handler APIHandler) CreateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
func (handler APIHandler) CreateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
//id := ps.ByName("id")
|
//id := ps.ByName("id")
|
||||||
jq, err := handler.GetJSON(req)
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
name, err := jq.String("name")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tags, err := jq.ArrayOfStrings("tags")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := jq.String("content")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
createdAt := time.Now()
|
createdAt := time.Now()
|
||||||
|
|
||||||
dict := model2.Dict{
|
dict := model2.Dict{
|
||||||
ID: util.GetUUID(),
|
ID: util.GetUUID(),
|
||||||
Name: name,
|
|
||||||
Tags: tags,
|
|
||||||
Content: []byte(content),
|
|
||||||
CreatedAt: createdAt,
|
CreatedAt: createdAt,
|
||||||
UpdatedAt: createdAt,
|
UpdatedAt: createdAt,
|
||||||
}
|
}
|
||||||
|
err := handler.DecodeJSON(req, &dict)
|
||||||
|
if err != nil {
|
||||||
|
handler.WriteJSON(w, map[string]interface{}{
|
||||||
|
"payload": nil,
|
||||||
|
"errno": "E100001",
|
||||||
|
"errmsg": err.Error(),
|
||||||
|
}, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = orm.Save(dict)
|
err = orm.Save(dict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -103,41 +90,18 @@ func (handler APIHandler) DeleteDictItemAction(w http.ResponseWriter, req *http.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler APIHandler) UpdateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
func (handler APIHandler) UpdateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
jq, err := handler.GetJSON(req)
|
dict := model2.Dict{}
|
||||||
|
err := handler.DecodeJSON(req, &dict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler.Error(w, err)
|
handler.WriteJSON(w, map[string]interface{}{
|
||||||
|
"payload": nil,
|
||||||
|
"errno": "E100002",
|
||||||
|
"errmsg": err.Error(),
|
||||||
|
}, http.StatusOK)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
id, err := jq.String("id")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
name, err := jq.String("name")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tags, err := jq.ArrayOfStrings("tags")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := jq.String("content")
|
|
||||||
if err != nil {
|
|
||||||
handler.Error(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
updatedAt := time.Now()
|
|
||||||
|
|
||||||
dict := model2.Dict{
|
|
||||||
ID: id,
|
|
||||||
Name: name,
|
|
||||||
Tags: tags,
|
|
||||||
Content: []byte(content),
|
|
||||||
UpdatedAt: updatedAt,
|
|
||||||
}
|
}
|
||||||
|
dict.UpdatedAt = time.Now()
|
||||||
|
|
||||||
err = orm.Update(dict)
|
err = orm.Update(dict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,10 +4,13 @@ import (
|
||||||
"infini.sh/framework/core/api"
|
"infini.sh/framework/core/api"
|
||||||
"infini.sh/framework/core/ui"
|
"infini.sh/framework/core/ui"
|
||||||
"infini.sh/search-center/api/index_management"
|
"infini.sh/search-center/api/index_management"
|
||||||
|
"infini.sh/search-center/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init(cfg *config.AppConfig) {
|
||||||
handler := index_management.APIHandler{}
|
handler := index_management.APIHandler{
|
||||||
|
Config: cfg,
|
||||||
|
}
|
||||||
//ui.HandleUIMethod(api.POST, "/api/get_indices",index_management.API1)
|
//ui.HandleUIMethod(api.POST, "/api/get_indices",index_management.API1)
|
||||||
ui.HandleUIMethod(api.GET, "/api/dict/_search", handler.GetDictListAction)
|
ui.HandleUIMethod(api.GET, "/api/dict/_search", handler.GetDictListAction)
|
||||||
ui.HandleUIMethod(api.POST, "/api/dict/_create", handler.CreateDictItemAction)
|
ui.HandleUIMethod(api.POST, "/api/dict/_create", handler.CreateDictItemAction)
|
||||||
|
@ -15,4 +18,5 @@ func Init() {
|
||||||
ui.HandleUIMethod(api.DELETE, "/api/dict/:id", handler.DeleteDictItemAction)
|
ui.HandleUIMethod(api.DELETE, "/api/dict/:id", handler.DeleteDictItemAction)
|
||||||
//ui.HandleUIMethod(api.DELETE, "/api/dict/", handler.DeleteDictItemAction2)
|
//ui.HandleUIMethod(api.DELETE, "/api/dict/", handler.DeleteDictItemAction2)
|
||||||
ui.HandleUIMethod(api.POST, "/api/dict/_update", handler.UpdateDictItemAction)
|
ui.HandleUIMethod(api.POST, "/api/dict/_update", handler.UpdateDictItemAction)
|
||||||
|
ui.HandleUIMethod(api.POST, "/api/doc/:index", handler.HandleDocumentAction)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
IndexName string `config:"index_name"`
|
IndexName string `config:"index_name"`
|
||||||
ElasticConfig string `config:"elastic_config"`
|
Elasticsearch string `config:"elasticsearch"`
|
||||||
UILocalPath string `config:"ui_path"`
|
UILocalPath string `config:"ui_path"`
|
||||||
UILocalEnabled bool `config:"ui_local"`
|
UILocalEnabled bool `config:"ui_local"`
|
||||||
UIVFSEnabled bool `config:"ui_vfs"`
|
UIVFSEnabled bool `config:"ui_vfs"`
|
||||||
}
|
}
|
||||||
|
|
4
main.go
4
main.go
|
@ -47,7 +47,7 @@ func main() {
|
||||||
modules.Register()
|
modules.Register()
|
||||||
|
|
||||||
appConfig = &config.AppConfig{
|
appConfig = &config.AppConfig{
|
||||||
ElasticConfig: "default",
|
Elasticsearch: "default",
|
||||||
UILocalPath: ".public",
|
UILocalPath: ".public",
|
||||||
UIVFSEnabled: true,
|
UIVFSEnabled: true,
|
||||||
UILocalEnabled: true,
|
UILocalEnabled: true,
|
||||||
|
@ -62,7 +62,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//load web UI files
|
//load web UI files
|
||||||
appUI = &UI{config: appConfig}
|
appUI = &UI{Config: appConfig}
|
||||||
appUI.InitUI()
|
appUI.InitUI()
|
||||||
|
|
||||||
//start each module, with enabled provider
|
//start each module, with enabled provider
|
||||||
|
|
|
@ -2,7 +2,7 @@ elasticsearch:
|
||||||
- name: default
|
- name: default
|
||||||
enabled: true
|
enabled: true
|
||||||
endpoint: http://localhost:9200
|
endpoint: http://localhost:9200
|
||||||
index_prefix: infini-
|
index_prefix:
|
||||||
basic_auth:
|
basic_auth:
|
||||||
username: elastic
|
username: elastic
|
||||||
password: ZBdkVQUUdF1Sir4X4BGB
|
password: ZBdkVQUUdF1Sir4X4BGB
|
||||||
|
|
4
ui.go
4
ui.go
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
type UI struct {
|
type UI struct {
|
||||||
api.Handler
|
api.Handler
|
||||||
config *config.AppConfig
|
Config *config.AppConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h UI) InitUI() {
|
func (h UI) InitUI() {
|
||||||
|
@ -24,7 +24,7 @@ func (h UI) InitUI() {
|
||||||
|
|
||||||
ui.HandleUI("/", vfs.FileServer(vfs.VFS()))
|
ui.HandleUI("/", vfs.FileServer(vfs.VFS()))
|
||||||
|
|
||||||
uiapi.Init()
|
uiapi.Init(h.Config)
|
||||||
|
|
||||||
ui.HandleUIFunc("/api/", func(w http.ResponseWriter, req *http.Request) {
|
ui.HandleUIFunc("/api/", func(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Warn("api: ", req.URL, " not implemented")
|
log.Warn("api: ", req.URL, " not implemented")
|
||||||
|
|
|
@ -90,7 +90,7 @@ export default [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/data/indices/doc',
|
path: '/data/indices/doc',
|
||||||
component: './DataManagement/Document',
|
component: './DataManagement/Index',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/data/indices/template',
|
path: '/data/indices/template',
|
||||||
|
@ -129,7 +129,7 @@ export default [
|
||||||
},{
|
},{
|
||||||
path: '/data/doc',
|
path: '/data/doc',
|
||||||
name: 'query',
|
name: 'query',
|
||||||
component: './DataManagement/Query',
|
component: './DataManagement/Document',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,610 +1,392 @@
|
||||||
import React, { PureComponent, Fragment } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import {
|
import { Col, Form, Row,Select, Input, Card,Icon, Table, InputNumber, Popconfirm,
|
||||||
Row,
|
Divider,Button,Tooltip, Cascader } from 'antd';
|
||||||
Col,
|
const {Option} = Select;
|
||||||
Card,
|
|
||||||
Form,
|
|
||||||
Input,
|
|
||||||
Button,
|
|
||||||
Modal,
|
|
||||||
message,
|
|
||||||
Divider,
|
|
||||||
Drawer,
|
|
||||||
Tabs,
|
|
||||||
Descriptions,
|
|
||||||
Menu,
|
|
||||||
Dropdown,
|
|
||||||
Icon
|
|
||||||
} from 'antd';
|
|
||||||
import StandardTable from '@/components/StandardTable';
|
|
||||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
|
||||||
|
|
||||||
import styles from '../List/TableList.less';
|
const EditableContext = React.createContext();
|
||||||
import JSONPretty from 'react-json-prettify';
|
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
|
||||||
const { TextArea } = Input;
|
|
||||||
const {TabPane} = Tabs;
|
|
||||||
|
|
||||||
class JSONWrapper extends PureComponent {
|
|
||||||
state ={
|
|
||||||
height: 400,
|
|
||||||
}
|
|
||||||
componentDidMount(){
|
|
||||||
|
|
||||||
let getElementTop = (elem)=>{
|
|
||||||
var elemTop=elem.offsetTop;
|
|
||||||
elem=elem.offsetParent;
|
|
||||||
|
|
||||||
while(elem!=null){
|
|
||||||
elemTop+=elem.offsetTop;
|
|
||||||
elem=elem.offsetParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elemTop;
|
|
||||||
|
|
||||||
|
class EditableCell extends React.Component {
|
||||||
|
getInput = () => {
|
||||||
|
let {record, dataIndex} = this.props;
|
||||||
|
if (typeof record[dataIndex] === 'number') {
|
||||||
|
return <InputNumber />;
|
||||||
}
|
}
|
||||||
console.log(getElementTop(this.refs.jsonw));
|
return <Input />;
|
||||||
this.setState({height: window.innerHeight - getElementTop(this.refs.jsonw) -50});
|
};
|
||||||
|
|
||||||
|
renderCell = ({ getFieldDecorator }) => {
|
||||||
|
const {
|
||||||
|
editing,
|
||||||
|
dataIndex,
|
||||||
|
title,
|
||||||
|
record,
|
||||||
|
index,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
} = this.props;
|
||||||
|
return (
|
||||||
|
<td {...restProps}>
|
||||||
|
{editing ? (
|
||||||
|
<Form.Item style={{ margin: 0 }}>
|
||||||
|
{getFieldDecorator(dataIndex, {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `Please Input ${title}!`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: record[dataIndex],
|
||||||
|
})(this.getInput())}
|
||||||
|
</Form.Item>
|
||||||
|
) : (
|
||||||
|
children
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
render(){
|
|
||||||
return (
|
@Form.create()
|
||||||
<div id="jsonw" ref="jsonw" onClick={()=>{console.log(document.getElementById('jsonw').offsetTop)}} style={{overflow:"scroll", height: this.state.height}}> {this.props.children}</div>
|
class EditableTable extends React.Component {
|
||||||
)
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.operField = {
|
||||||
|
title: 'operation',
|
||||||
|
dataIndex: 'operation',
|
||||||
|
render: (text, record) => {
|
||||||
|
const { editingKey } = this.props.doclist;
|
||||||
|
const editable = this.isEditing(record);
|
||||||
|
return editable ? (
|
||||||
|
<span>
|
||||||
|
<EditableContext.Consumer>
|
||||||
|
{form => (
|
||||||
|
<a
|
||||||
|
onClick={() => this.save(form, record.id)}
|
||||||
|
style={{ marginRight: 8 }}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</EditableContext.Consumer>
|
||||||
|
<Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(record.id)}>
|
||||||
|
<a>Cancel</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</span>
|
||||||
|
) : (<div>
|
||||||
|
<a disabled={editingKey !== ''} onClick={() => this.edit(record)}>
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
<Divider type="vertical"/>
|
||||||
|
<Popconfirm title="Sure to delete?" onConfirm={() => this.delete(record)}>
|
||||||
|
<a>Delete</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
isEditing = record => record.id === this.props.doclist.editingKey;
|
||||||
|
|
||||||
|
cancel = () => {
|
||||||
|
const {dispatch, doclist} = this.props;
|
||||||
|
if(!doclist.isAddNew){
|
||||||
|
dispatch({
|
||||||
|
type: 'document/saveData',
|
||||||
|
payload: { editingKey: '' },
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
dispatch({
|
||||||
|
type: 'document/cancelNew',
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
save(form, key) {
|
||||||
|
const {dispatch,doclist} = this.props;
|
||||||
|
form.validateFields((error, row) => {
|
||||||
|
if (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log(row, key, doclist._index);
|
||||||
|
if(!doclist.isAddNew){
|
||||||
|
dispatch({
|
||||||
|
type: 'document/saveDocItem',
|
||||||
|
payload: {
|
||||||
|
index: doclist._index,
|
||||||
|
data: {
|
||||||
|
id: key,
|
||||||
|
...row,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dispatch({
|
||||||
|
type: 'document/addDocItem',
|
||||||
|
payload: {
|
||||||
|
index: doclist.index,
|
||||||
|
data: row,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
edit(record) {
|
||||||
|
const {dispatch} = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'document/saveData',
|
||||||
|
payload: { editingKey: record.id, _index: record._index }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(record) {
|
||||||
|
const {dispatch} = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'document/deleteDocItem',
|
||||||
|
payload: {
|
||||||
|
index: record._index,
|
||||||
|
data: {
|
||||||
|
id: record.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
handlePageChange = (pageIndex)=>{
|
||||||
|
const {fetchData, doclist} = this.props;
|
||||||
|
fetchData({
|
||||||
|
pageIndex: pageIndex,
|
||||||
|
pageSize: doclist.pageSize,
|
||||||
|
index: doclist.index,
|
||||||
|
cluster: doclist.cluster,
|
||||||
|
filter: doclist.filter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowSizeChange(current, pageSize) {
|
||||||
|
console.log(current, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {doclist} = this.props;
|
||||||
|
let columns = [];
|
||||||
|
if(doclist.data && doclist.data.length > 0 ){
|
||||||
|
for(let key in doclist.data[0]){
|
||||||
|
if(["_index"].includes(key)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let col = {
|
||||||
|
title: key,
|
||||||
|
dataIndex: key,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (text)=>(<Tooltip placement="top" title={text}>{text}</Tooltip>),
|
||||||
|
onCell: record => ({
|
||||||
|
record,
|
||||||
|
dataIndex: key,
|
||||||
|
title: key,
|
||||||
|
editing: this.isEditing(record),
|
||||||
|
// onMouseEnter: event => {console.log(event)},
|
||||||
|
// onMouseLeave: event => {},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
if(["id"].includes(key)){
|
||||||
|
col.onCell = "";
|
||||||
|
}
|
||||||
|
columns.push(col)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
columns.push(this.operField);
|
||||||
|
//console.log(columns);
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
body: {
|
||||||
|
cell: EditableCell,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<EditableContext.Provider value={this.props.form}>
|
||||||
|
<Table
|
||||||
|
components={components}
|
||||||
|
bordered
|
||||||
|
rowKey="id"
|
||||||
|
size="small"
|
||||||
|
loading={doclist.isLoading}
|
||||||
|
dataSource={doclist.data}
|
||||||
|
columns={columns}
|
||||||
|
rowClassName="editable-row"
|
||||||
|
pagination={{
|
||||||
|
onChange: this.cancel,
|
||||||
|
//showSizeChanger: true,
|
||||||
|
//onShowSizeChange: this.onShowSizeChange,
|
||||||
|
total: doclist.total? doclist.total.value: 0,
|
||||||
|
pageSize: doclist.pageSize,
|
||||||
|
current: doclist.pageIndex,
|
||||||
|
onChange: this.handlePageChange,
|
||||||
|
showTotal: (total, range) => `Total ${total} items`,
|
||||||
|
size: 'small',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</EditableContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const CreateForm = Form.create()(props => {
|
|
||||||
const { modalVisible, form, handleAdd, handleModalVisible } = props;
|
|
||||||
const okHandle = () => {
|
|
||||||
form.validateFields((err, fieldsValue) => {
|
|
||||||
if (err) return;
|
|
||||||
form.resetFields();
|
|
||||||
handleAdd(fieldsValue);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
destroyOnClose
|
|
||||||
title="新建索引"
|
|
||||||
visible={modalVisible}
|
|
||||||
width={640}
|
|
||||||
onOk={okHandle}
|
|
||||||
onCancel={() => handleModalVisible()}
|
|
||||||
>
|
|
||||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引名称">
|
|
||||||
{form.getFieldDecorator('index', {
|
|
||||||
rules: [{ required: true, message: '请输入至少五个字符的名称!', min: 5 }],
|
|
||||||
})(<Input placeholder="请输入名称" />)}
|
|
||||||
</FormItem>
|
|
||||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引设置">
|
|
||||||
{form.getFieldDecorator('settings', {
|
|
||||||
rules: [{ required: true }],
|
|
||||||
})(<TextArea
|
|
||||||
style={{ minHeight: 24 }}
|
|
||||||
placeholder="请输入"
|
|
||||||
rows={9}
|
|
||||||
/>)}
|
|
||||||
</FormItem>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const UpdateForm = Form.create()(props => {
|
@connect(({document})=>({
|
||||||
const { updateModalVisible, handleUpdateModalVisible, handleUpdate,values,form } = props;
|
document
|
||||||
|
|
||||||
const okHandle = () => {
|
|
||||||
form.validateFields((err, fieldsValue) => {
|
|
||||||
if (err) return;
|
|
||||||
form.resetFields();
|
|
||||||
handleUpdate(fieldsValue);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
destroyOnClose
|
|
||||||
title="索引设置"
|
|
||||||
visible={updateModalVisible}
|
|
||||||
width={640}
|
|
||||||
onOk={okHandle}
|
|
||||||
onCancel={() => handleUpdateModalVisible()}
|
|
||||||
>
|
|
||||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引名称">
|
|
||||||
{form.getFieldDecorator('index', {
|
|
||||||
initialValue: values.index,
|
|
||||||
rules: [{ required: true, message: '请输入至少五个字符的名称!', min: 5 }],
|
|
||||||
})(<Input placeholder="请输入名称" />)}
|
|
||||||
</FormItem>
|
|
||||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引设置">
|
|
||||||
{form.getFieldDecorator('settings', {
|
|
||||||
initialValue: values.processors,
|
|
||||||
rules: [{ required: true }],
|
|
||||||
})(<TextArea
|
|
||||||
style={{ minHeight: 24 }}
|
|
||||||
placeholder="请输入"
|
|
||||||
rows={9}
|
|
||||||
/>)}
|
|
||||||
</FormItem>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* eslint react/no-multi-comp:0 */
|
|
||||||
@connect(({ pipeline, loading }) => ({
|
|
||||||
pipeline,
|
|
||||||
loading: loading.models.pipeline,
|
|
||||||
}))
|
}))
|
||||||
@Form.create()
|
@Form.create()
|
||||||
class Document extends PureComponent {
|
class Doucment extends React.Component {
|
||||||
state = {
|
state={
|
||||||
modalVisible: false,
|
bodyDisplay: 'none',
|
||||||
updateModalVisible: false,
|
|
||||||
expandForm: false,
|
|
||||||
selectedRows: [],
|
|
||||||
formValues: {},
|
|
||||||
updateFormValues: {},
|
|
||||||
drawerVisible: false,
|
|
||||||
editingIndex:{},
|
|
||||||
};
|
|
||||||
datasource = `[{"health":"green","status":"open","index":"blogs_fixed","uuid":"Q6zngGf9QVaWqpV0lF-0nw","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"594","store.size":"17.9mb","pri.store.size":"8.9mb"},{"health":"red","status":"open","index":"elastic_qa","uuid":"_qkVlQ5LRoOKffV-nFj8Uw","pri":"1","rep":"1","docs.count":null,"docs.deleted":null,"store.size":null,"pri.store.size":null},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000001","uuid":"fgTtyl62Tc6F1ddJfPwqHA","pri":"1","rep":"1","docs.count":"20","docs.deleted":"0","store.size":"25kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":"blogs","uuid":"Mb2n4wnNQSKqSToI_QO0Yg","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"0","store.size":"11mb","pri.store.size":"5.5mb"},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000002","uuid":"8GpbwnDXR2KJUsw6srLnWw","pri":"1","rep":"1","docs.count":"9","docs.deleted":"0","store.size":"96.9kb","pri.store.size":"48.4kb"},{"health":"green","status":"open","index":".apm-agent-configuration","uuid":"vIaV9k2VS-W48oUOe2xNWA","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"logs_server1","uuid":"u56jv2AyR2KOkruOfxIAnA","pri":"1","rep":"1","docs.count":"5386","docs.deleted":"0","store.size":"5.1mb","pri.store.size":"2.5mb"},{"health":"green","status":"open","index":".kibana_1","uuid":"dBCrfVblRPGVlYAIlP_Duw","pri":"1","rep":"1","docs.count":"3187","docs.deleted":"50","store.size":"24.8mb","pri.store.size":"12.4mb"},{"health":"green","status":"open","index":".tasks","uuid":"3RafayGeSNiqglO2BHof9Q","pri":"1","rep":"1","docs.count":"3","docs.deleted":"0","store.size":"39.9kb","pri.store.size":"19.9kb"},{"health":"green","status":"open","index":"filebeat-7.9.0-elastic_qa","uuid":"tktSYU14S3CrsrJb0ybpSQ","pri":"1","rep":"1","docs.count":"3009880","docs.deleted":"0","store.size":"1.6gb","pri.store.size":"850.1mb"},{"health":"green","status":"open","index":"analysis_test","uuid":"6ZHEAW1ST_qfg7mo4Bva4w","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":".apm-custom-link","uuid":"Y4N2TeVERrGacEGwY-NPAQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"kibana_sample_data_ecommerce","uuid":"4FIWJKhGSr6bE72R0xEQyA","pri":"1","rep":"1","docs.count":"4675","docs.deleted":"0","store.size":"9.2mb","pri.store.size":"4.6mb"},{"health":"green","status":"open","index":".kibana_task_manager_1","uuid":"9afyndU_Q26oqOiEIoqRJw","pri":"1","rep":"1","docs.count":"6","docs.deleted":"2","store.size":"378.8kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":".async-search","uuid":"2VbJgnN7SsqC-DWN64yXUQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"3.9kb","pri.store.size":"3.7kb"}]`;
|
|
||||||
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
title: '索引名称',
|
|
||||||
dataIndex: 'index',
|
|
||||||
render: (text, record) => (
|
|
||||||
<a onClick={()=>{
|
|
||||||
this.setState({
|
|
||||||
editingIndex: record,
|
|
||||||
drawerVisible: true,
|
|
||||||
});
|
|
||||||
}}>{text}</a>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '文档数',
|
|
||||||
dataIndex: 'docs.count',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '主分片数',
|
|
||||||
dataIndex: 'pri'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '从分片数',
|
|
||||||
dataIndex: 'rep'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储大小',
|
|
||||||
dataIndex: 'store.size'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
render: (text, record) => (
|
|
||||||
<Fragment>
|
|
||||||
{/* <a onClick={() => this.handleUpdateModalVisible(true, record)}>设置</a>
|
|
||||||
<Divider type="vertical" /> */}
|
|
||||||
<a onClick={() => {
|
|
||||||
this.state.selectedRows.push(record);
|
|
||||||
this.handleDeleteClick();
|
|
||||||
}}>删除</a>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
<a onClick={() => {
|
|
||||||
this.state.selectedRows.push(record);
|
|
||||||
this.handleDeleteClick();
|
|
||||||
}}>文档管理</a>
|
|
||||||
</Fragment>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
// dispatch({
|
|
||||||
// type: 'pipeline/fetch',
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
fetchData = (params) => {
|
||||||
const { dispatch } = this.props;
|
const {dispatch} = this.props;
|
||||||
const { formValues } = this.state;
|
|
||||||
|
|
||||||
const filters = Object.keys(filtersArg).reduce((obj, key) => {
|
|
||||||
const newObj = { ...obj };
|
|
||||||
newObj[key] = getValue(filtersArg[key]);
|
|
||||||
return newObj;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
currentPage: pagination.current,
|
|
||||||
pageSize: pagination.pageSize,
|
|
||||||
...formValues,
|
|
||||||
...filters,
|
|
||||||
};
|
|
||||||
if (sorter.field) {
|
|
||||||
params.sorter = `${sorter.field}_${sorter.order}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'pipeline/fetch',
|
type: 'document/fetchDocList',
|
||||||
payload: params,
|
payload: params,
|
||||||
});
|
})
|
||||||
};
|
|
||||||
|
|
||||||
handleFormReset = () => {
|
|
||||||
const { form, dispatch } = this.props;
|
|
||||||
form.resetFields();
|
|
||||||
this.setState({
|
|
||||||
formValues: {},
|
|
||||||
});
|
|
||||||
dispatch({
|
|
||||||
type: 'pipeline/fetch',
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleDeleteClick = e => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
const { selectedRows } = this.state;
|
|
||||||
|
|
||||||
if (!selectedRows) return;
|
|
||||||
dispatch({
|
|
||||||
type: 'pipeline/delete',
|
|
||||||
payload: {
|
|
||||||
key: selectedRows.map(row => row.name),
|
|
||||||
},
|
|
||||||
callback: () => {
|
|
||||||
this.setState({
|
|
||||||
selectedRows: [],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSelectRows = rows => {
|
|
||||||
this.setState({
|
|
||||||
selectedRows: rows,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSearch = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const { dispatch, form } = this.props;
|
|
||||||
|
|
||||||
form.validateFields((err, fieldsValue) => {
|
|
||||||
if (err) return;
|
|
||||||
|
|
||||||
const values = {
|
|
||||||
...fieldsValue,
|
|
||||||
updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
formValues: values,
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: 'rule/fetch',
|
|
||||||
payload: values,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleModalVisible = flag => {
|
|
||||||
this.setState({
|
|
||||||
modalVisible: !!flag,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleUpdateModalVisible = (flag, record) => {
|
|
||||||
this.setState({
|
|
||||||
updateModalVisible: !!flag,
|
|
||||||
updateFormValues: record || {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleAdd = fields => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch({
|
|
||||||
type: 'pipeline/add',
|
|
||||||
payload: {
|
|
||||||
name: fields.name,
|
|
||||||
desc: fields.desc,
|
|
||||||
processors: fields.processors,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
message.success('添加成功');
|
|
||||||
this.handleModalVisible();
|
|
||||||
};
|
|
||||||
|
|
||||||
handleUpdate = fields => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch({
|
|
||||||
type: 'pipeline/update',
|
|
||||||
payload: {
|
|
||||||
name: fields.name,
|
|
||||||
desc: fields.desc,
|
|
||||||
processors: fields.processors,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
message.success('修改成功');
|
|
||||||
this.handleUpdateModalVisible();
|
|
||||||
};
|
|
||||||
|
|
||||||
renderSimpleForm() {
|
|
||||||
const {
|
|
||||||
form: { getFieldDecorator },
|
|
||||||
} = this.props;
|
|
||||||
return (
|
|
||||||
<Form onSubmit={this.handleSearch} layout="inline">
|
|
||||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
|
||||||
<Col md={8} sm={24}>
|
|
||||||
<FormItem label="索引名称">
|
|
||||||
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
|
|
||||||
</FormItem>
|
|
||||||
</Col>
|
|
||||||
<Col md={8} sm={24}>
|
|
||||||
<span className={styles.submitButtons}>
|
|
||||||
<Button type="primary" htmlType="submit">
|
|
||||||
查询
|
|
||||||
</Button>
|
|
||||||
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
|
|
||||||
重置
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderForm() {
|
componentDidMount(){
|
||||||
return this.renderSimpleForm();
|
this.fetchData({
|
||||||
|
pageSize: 10,
|
||||||
|
pageIndex: 1,
|
||||||
|
index: 'infini-test',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
handleNewClick = ()=>{
|
||||||
const data = {
|
const {dispatch, document} = this.props;
|
||||||
list: JSON.parse(this.datasource),
|
if(!document.data || document.data.length == 0 || document.isAddNew){
|
||||||
pagination: {
|
return;
|
||||||
pageSize: 5,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const { selectedRows, modalVisible, updateModalVisible, updateFormValues,editingIndex, drawerVisible } = this.state;
|
|
||||||
const parentMethods = {
|
|
||||||
handleAdd: this.handleAdd,
|
|
||||||
handleModalVisible: this.handleModalVisible,
|
|
||||||
};
|
|
||||||
const updateMethods = {
|
|
||||||
handleUpdateModalVisible: this.handleUpdateModalVisible,
|
|
||||||
handleUpdate: this.handleUpdate,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<Card bordered={false}>
|
|
||||||
<div className={styles.tableList}>
|
|
||||||
<div className={styles.tableListForm}>{this.renderForm()}</div>
|
|
||||||
<div className={styles.tableListOperator}>
|
|
||||||
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
|
|
||||||
新建
|
|
||||||
</Button>
|
|
||||||
{selectedRows.length > 0 && (
|
|
||||||
<span>
|
|
||||||
<Button onClick={() => this.handleDeleteClick()}>删除</Button>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<StandardTable
|
|
||||||
selectedRows={selectedRows}
|
|
||||||
data={data}
|
|
||||||
columns={this.columns}
|
|
||||||
onSelectRow={this.handleSelectRows}
|
|
||||||
onChange={this.handleStandardTableChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
<CreateForm {...parentMethods} modalVisible={modalVisible} />
|
|
||||||
{updateFormValues && Object.keys(updateFormValues).length ? (
|
|
||||||
<UpdateForm
|
|
||||||
{...updateMethods}
|
|
||||||
updateModalVisible={updateModalVisible}
|
|
||||||
values={updateFormValues}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<Drawer title={editingIndex.index}
|
|
||||||
visible={drawerVisible}
|
|
||||||
onClose={()=>{
|
|
||||||
this.setState({
|
|
||||||
drawerVisible: false,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
width={640}
|
|
||||||
>
|
|
||||||
<Tabs defaultActiveKey="1" onChange={()=>{}}>
|
|
||||||
<TabPane tab="Summary" key="1">
|
|
||||||
<Descriptions title="General" column={2}>
|
|
||||||
<Descriptions.Item label="Health">green</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Status">open</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Primaries">1</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Replicas">0</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Docs Count">5</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Docs Deleted">0</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Storage Size">115.3kb</Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Primary Storage Size"></Descriptions.Item>
|
|
||||||
<Descriptions.Item label="Alias">
|
|
||||||
</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tab="Mappings" key="2">
|
|
||||||
<JSONWrapper>
|
|
||||||
<JSONPretty json={JSON.parse(`{
|
|
||||||
"mappings": {
|
|
||||||
"_doc": {
|
|
||||||
"dynamic": "strict",
|
|
||||||
"_meta": {
|
|
||||||
"migrationMappingPropertyHashes": {
|
|
||||||
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
|
|
||||||
"originId": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"task": "235412e52d09e7165fac8a67a43ad6b4",
|
|
||||||
"updated_at": "00da57df13e94e9d98437d13ace4bfe0",
|
|
||||||
"references": "7997cf5a56cc02bdc9c93361bde732b0",
|
|
||||||
"namespace": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"type": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"namespaces": "2f4316de49999235636386fe51dc06c1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"migrationVersion": {
|
|
||||||
"dynamic": "true",
|
|
||||||
"properties": {
|
|
||||||
"task": {
|
|
||||||
"type": "text",
|
|
||||||
"fields": {
|
|
||||||
"keyword": {
|
|
||||||
"type": "keyword",
|
|
||||||
"ignore_above": 256
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"namespace": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"namespaces": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"originId": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"references": {
|
|
||||||
"type": "nested",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"task": {
|
|
||||||
"properties": {
|
|
||||||
"attempts": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ownerId": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
"retryAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"runAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"schedule": {
|
|
||||||
"properties": {
|
|
||||||
"interval": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scheduledAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"scope": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"startedAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"taskType": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
let keys = Object.keys(document.data[0])
|
||||||
|
let newDoc = {};
|
||||||
|
for(let key of keys){
|
||||||
|
newDoc[key] = ""
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: 'document/_addNew',
|
||||||
|
payload: {
|
||||||
|
docItem: newDoc,
|
||||||
|
extra: {
|
||||||
|
isAddNew: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
`)} theme={{
|
handleSearchClick = (value)=>{
|
||||||
background: '#F5F7FA',
|
const [cluster, index] = this.indexEl.state.value;
|
||||||
brace: '#343741',
|
let targetIndex = index;
|
||||||
keyQuotes: '#343741',
|
if(value != ""){
|
||||||
valueQuotes: '#343741',
|
targetIndex = value;
|
||||||
colon: '#343741',
|
}
|
||||||
comma: '#343741',
|
console.log(targetIndex);
|
||||||
key: '#343741',
|
this.fetchData({
|
||||||
value: {
|
cluster,
|
||||||
string: '#343741',
|
index: targetIndex,
|
||||||
null: '#343741',
|
pageSize: 10,
|
||||||
number: '#343741',
|
pageIndex: 1,
|
||||||
boolean: '#343741',
|
filter: this.filterEl.state.value,
|
||||||
},
|
})
|
||||||
bracket: '#343741',
|
}
|
||||||
}} /></JSONWrapper>
|
|
||||||
</TabPane>
|
renderNew = ()=>{
|
||||||
<TabPane tab="Stats" key="3">
|
const {indices} = this.props.document;
|
||||||
Content of Tab Pane 3
|
if((indices && indices.length > 1)){
|
||||||
</TabPane>
|
return;
|
||||||
<TabPane tab="Edit settings" key="4">
|
}
|
||||||
Content of Tab Pane 3
|
return (
|
||||||
</TabPane>
|
<div>
|
||||||
</Tabs>
|
{(indices && indices.length > 1) ? (<Select style={{width: 200, marginRight:5}} placeholder="please select a index">
|
||||||
<div style={{position:'absolute', bottom: 10}}>
|
{indices.map(item=>{
|
||||||
<Dropdown
|
return (<Select.Option key={item} label={item}>{item}</Select.Option>)
|
||||||
placement="topLeft"
|
})}
|
||||||
overlay={(
|
</Select>) : ''}
|
||||||
<Menu onClick={()=>{}}>
|
<Button type="primary" icon="plus" onClick={this.handleNewClick}>新建</Button>
|
||||||
<Menu.Item key="1">
|
</div>
|
||||||
<Icon type="delete" />
|
)
|
||||||
Delete
|
}
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item key="2">
|
render(){
|
||||||
<Icon type="edit" />
|
// const {getFieldDecorator} = this.props.form;
|
||||||
Edit
|
//console.log(this.props.document);
|
||||||
</Menu.Item>
|
const options =[
|
||||||
<Menu.Item key="3">
|
{
|
||||||
<Icon type="close" />
|
value: 'single-es',
|
||||||
Close
|
label: 'single-es',
|
||||||
</Menu.Item>
|
children: [
|
||||||
</Menu>
|
{
|
||||||
)}>
|
value: 'infini-test',
|
||||||
<Button type="primary">
|
label: 'infini-test',
|
||||||
Manage <Icon type="up" />
|
}
|
||||||
</Button>
|
]}];
|
||||||
</Dropdown>
|
return (
|
||||||
|
<div>
|
||||||
|
<Card>
|
||||||
|
<Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
|
||||||
|
<Col span={20}>
|
||||||
|
<Input.Group compact>
|
||||||
|
<Cascader
|
||||||
|
options={options}
|
||||||
|
ref={el=>{this.indexEl=el}}
|
||||||
|
style={{width: '20%'}}
|
||||||
|
onChange={(value, selectedOptions)=>{console.log(value)}}
|
||||||
|
placeholder="Please select index"
|
||||||
|
showSearch={{filter: (inputValue, path)=>path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1) }}
|
||||||
|
/>
|
||||||
|
<Input.Search
|
||||||
|
style={{width:"80%"}}
|
||||||
|
placeholder="input rewrite index or index pattern"
|
||||||
|
enterButton="execute"
|
||||||
|
onSearch={this.handleSearchClick}
|
||||||
|
/>
|
||||||
|
</Input.Group>
|
||||||
|
</Col>
|
||||||
|
<Col span={4}>
|
||||||
|
<a style={{marginTop:5,display:'block'}} onClick={(e)=>{
|
||||||
|
this.setState((preState)=>{
|
||||||
|
if(preState.bodyDisplay == 'none') {
|
||||||
|
return {
|
||||||
|
bodyDisplay: 'block',
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
bodyDisplay: 'none'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}>{this.state.bodyDisplay == 'none' ? '高级':'收起'}<Icon type="down" /></a>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{display: this.state.bodyDisplay}} gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
|
||||||
|
<Col span={20}>
|
||||||
|
<Input.TextArea ref={el=>{this.filterEl=el}} placeholder="input query filter (elasticsearch query DSL)" rows={8}/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
<div>
|
||||||
|
<Card title={`Index: ${this.props.document.index}`}
|
||||||
|
bodyStyle={{padding:0, paddingBottom: 24}}
|
||||||
|
extra={this.renderNew()}
|
||||||
|
bordered={false}>
|
||||||
|
<EditableTable doclist={this.props.document} dispatch={this.props.dispatch}
|
||||||
|
fetchData={(params)=>{this.fetchData(params)}}/>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
)
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Document;
|
export default Doucment;
|
|
@ -0,0 +1,610 @@
|
||||||
|
import React, { PureComponent, Fragment } from 'react';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import {
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Card,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Button,
|
||||||
|
Modal,
|
||||||
|
message,
|
||||||
|
Divider,
|
||||||
|
Drawer,
|
||||||
|
Tabs,
|
||||||
|
Descriptions,
|
||||||
|
Menu,
|
||||||
|
Dropdown,
|
||||||
|
Icon
|
||||||
|
} from 'antd';
|
||||||
|
import StandardTable from '@/components/StandardTable';
|
||||||
|
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||||
|
|
||||||
|
import styles from '../List/TableList.less';
|
||||||
|
import JSONPretty from 'react-json-prettify';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
const {TabPane} = Tabs;
|
||||||
|
|
||||||
|
class JSONWrapper extends PureComponent {
|
||||||
|
state ={
|
||||||
|
height: 400,
|
||||||
|
}
|
||||||
|
componentDidMount(){
|
||||||
|
|
||||||
|
let getElementTop = (elem)=>{
|
||||||
|
var elemTop=elem.offsetTop;
|
||||||
|
elem=elem.offsetParent;
|
||||||
|
|
||||||
|
while(elem!=null){
|
||||||
|
elemTop+=elem.offsetTop;
|
||||||
|
elem=elem.offsetParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return elemTop;
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log(getElementTop(this.refs.jsonw));
|
||||||
|
this.setState({height: window.innerHeight - getElementTop(this.refs.jsonw) -50});
|
||||||
|
}
|
||||||
|
render(){
|
||||||
|
return (
|
||||||
|
<div id="jsonw" ref="jsonw" onClick={()=>{console.log(document.getElementById('jsonw').offsetTop)}} style={{overflow:"scroll", height: this.state.height}}> {this.props.children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateForm = Form.create()(props => {
|
||||||
|
const { modalVisible, form, handleAdd, handleModalVisible } = props;
|
||||||
|
const okHandle = () => {
|
||||||
|
form.validateFields((err, fieldsValue) => {
|
||||||
|
if (err) return;
|
||||||
|
form.resetFields();
|
||||||
|
handleAdd(fieldsValue);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
destroyOnClose
|
||||||
|
title="新建索引"
|
||||||
|
visible={modalVisible}
|
||||||
|
width={640}
|
||||||
|
onOk={okHandle}
|
||||||
|
onCancel={() => handleModalVisible()}
|
||||||
|
>
|
||||||
|
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引名称">
|
||||||
|
{form.getFieldDecorator('index', {
|
||||||
|
rules: [{ required: true, message: '请输入至少五个字符的名称!', min: 5 }],
|
||||||
|
})(<Input placeholder="请输入名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引设置">
|
||||||
|
{form.getFieldDecorator('settings', {
|
||||||
|
rules: [{ required: true }],
|
||||||
|
})(<TextArea
|
||||||
|
style={{ minHeight: 24 }}
|
||||||
|
placeholder="请输入"
|
||||||
|
rows={9}
|
||||||
|
/>)}
|
||||||
|
</FormItem>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const UpdateForm = Form.create()(props => {
|
||||||
|
const { updateModalVisible, handleUpdateModalVisible, handleUpdate,values,form } = props;
|
||||||
|
|
||||||
|
const okHandle = () => {
|
||||||
|
form.validateFields((err, fieldsValue) => {
|
||||||
|
if (err) return;
|
||||||
|
form.resetFields();
|
||||||
|
handleUpdate(fieldsValue);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
destroyOnClose
|
||||||
|
title="索引设置"
|
||||||
|
visible={updateModalVisible}
|
||||||
|
width={640}
|
||||||
|
onOk={okHandle}
|
||||||
|
onCancel={() => handleUpdateModalVisible()}
|
||||||
|
>
|
||||||
|
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引名称">
|
||||||
|
{form.getFieldDecorator('index', {
|
||||||
|
initialValue: values.index,
|
||||||
|
rules: [{ required: true, message: '请输入至少五个字符的名称!', min: 5 }],
|
||||||
|
})(<Input placeholder="请输入名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="索引设置">
|
||||||
|
{form.getFieldDecorator('settings', {
|
||||||
|
initialValue: values.processors,
|
||||||
|
rules: [{ required: true }],
|
||||||
|
})(<TextArea
|
||||||
|
style={{ minHeight: 24 }}
|
||||||
|
placeholder="请输入"
|
||||||
|
rows={9}
|
||||||
|
/>)}
|
||||||
|
</FormItem>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* eslint react/no-multi-comp:0 */
|
||||||
|
@connect(({ pipeline, loading }) => ({
|
||||||
|
pipeline,
|
||||||
|
loading: loading.models.pipeline,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class Index extends PureComponent {
|
||||||
|
state = {
|
||||||
|
modalVisible: false,
|
||||||
|
updateModalVisible: false,
|
||||||
|
expandForm: false,
|
||||||
|
selectedRows: [],
|
||||||
|
formValues: {},
|
||||||
|
updateFormValues: {},
|
||||||
|
drawerVisible: false,
|
||||||
|
editingIndex:{},
|
||||||
|
};
|
||||||
|
datasource = `[{"health":"green","status":"open","index":"blogs_fixed","uuid":"Q6zngGf9QVaWqpV0lF-0nw","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"594","store.size":"17.9mb","pri.store.size":"8.9mb"},{"health":"red","status":"open","index":"elastic_qa","uuid":"_qkVlQ5LRoOKffV-nFj8Uw","pri":"1","rep":"1","docs.count":null,"docs.deleted":null,"store.size":null,"pri.store.size":null},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000001","uuid":"fgTtyl62Tc6F1ddJfPwqHA","pri":"1","rep":"1","docs.count":"20","docs.deleted":"0","store.size":"25kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":"blogs","uuid":"Mb2n4wnNQSKqSToI_QO0Yg","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"0","store.size":"11mb","pri.store.size":"5.5mb"},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000002","uuid":"8GpbwnDXR2KJUsw6srLnWw","pri":"1","rep":"1","docs.count":"9","docs.deleted":"0","store.size":"96.9kb","pri.store.size":"48.4kb"},{"health":"green","status":"open","index":".apm-agent-configuration","uuid":"vIaV9k2VS-W48oUOe2xNWA","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"logs_server1","uuid":"u56jv2AyR2KOkruOfxIAnA","pri":"1","rep":"1","docs.count":"5386","docs.deleted":"0","store.size":"5.1mb","pri.store.size":"2.5mb"},{"health":"green","status":"open","index":".kibana_1","uuid":"dBCrfVblRPGVlYAIlP_Duw","pri":"1","rep":"1","docs.count":"3187","docs.deleted":"50","store.size":"24.8mb","pri.store.size":"12.4mb"},{"health":"green","status":"open","index":".tasks","uuid":"3RafayGeSNiqglO2BHof9Q","pri":"1","rep":"1","docs.count":"3","docs.deleted":"0","store.size":"39.9kb","pri.store.size":"19.9kb"},{"health":"green","status":"open","index":"filebeat-7.9.0-elastic_qa","uuid":"tktSYU14S3CrsrJb0ybpSQ","pri":"1","rep":"1","docs.count":"3009880","docs.deleted":"0","store.size":"1.6gb","pri.store.size":"850.1mb"},{"health":"green","status":"open","index":"analysis_test","uuid":"6ZHEAW1ST_qfg7mo4Bva4w","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":".apm-custom-link","uuid":"Y4N2TeVERrGacEGwY-NPAQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"kibana_sample_data_ecommerce","uuid":"4FIWJKhGSr6bE72R0xEQyA","pri":"1","rep":"1","docs.count":"4675","docs.deleted":"0","store.size":"9.2mb","pri.store.size":"4.6mb"},{"health":"green","status":"open","index":".kibana_task_manager_1","uuid":"9afyndU_Q26oqOiEIoqRJw","pri":"1","rep":"1","docs.count":"6","docs.deleted":"2","store.size":"378.8kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":".async-search","uuid":"2VbJgnN7SsqC-DWN64yXUQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"3.9kb","pri.store.size":"3.7kb"}]`;
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
title: '索引名称',
|
||||||
|
dataIndex: 'index',
|
||||||
|
render: (text, record) => (
|
||||||
|
<a onClick={()=>{
|
||||||
|
this.setState({
|
||||||
|
editingIndex: record,
|
||||||
|
drawerVisible: true,
|
||||||
|
});
|
||||||
|
}}>{text}</a>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文档数',
|
||||||
|
dataIndex: 'docs.count',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '主分片数',
|
||||||
|
dataIndex: 'pri'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '从分片数',
|
||||||
|
dataIndex: 'rep'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '存储大小',
|
||||||
|
dataIndex: 'store.size'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
render: (text, record) => (
|
||||||
|
<Fragment>
|
||||||
|
{/* <a onClick={() => this.handleUpdateModalVisible(true, record)}>设置</a>
|
||||||
|
<Divider type="vertical" /> */}
|
||||||
|
<a onClick={() => {
|
||||||
|
this.state.selectedRows.push(record);
|
||||||
|
this.handleDeleteClick();
|
||||||
|
}}>删除</a>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<a onClick={() => {
|
||||||
|
this.state.selectedRows.push(record);
|
||||||
|
this.handleDeleteClick();
|
||||||
|
}}>文档管理</a>
|
||||||
|
</Fragment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
// dispatch({
|
||||||
|
// type: 'pipeline/fetch',
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
const { formValues } = this.state;
|
||||||
|
|
||||||
|
const filters = Object.keys(filtersArg).reduce((obj, key) => {
|
||||||
|
const newObj = { ...obj };
|
||||||
|
newObj[key] = getValue(filtersArg[key]);
|
||||||
|
return newObj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
currentPage: pagination.current,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
...formValues,
|
||||||
|
...filters,
|
||||||
|
};
|
||||||
|
if (sorter.field) {
|
||||||
|
params.sorter = `${sorter.field}_${sorter.order}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: 'pipeline/fetch',
|
||||||
|
payload: params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleFormReset = () => {
|
||||||
|
const { form, dispatch } = this.props;
|
||||||
|
form.resetFields();
|
||||||
|
this.setState({
|
||||||
|
formValues: {},
|
||||||
|
});
|
||||||
|
dispatch({
|
||||||
|
type: 'pipeline/fetch',
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleDeleteClick = e => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
const { selectedRows } = this.state;
|
||||||
|
|
||||||
|
if (!selectedRows) return;
|
||||||
|
dispatch({
|
||||||
|
type: 'pipeline/delete',
|
||||||
|
payload: {
|
||||||
|
key: selectedRows.map(row => row.name),
|
||||||
|
},
|
||||||
|
callback: () => {
|
||||||
|
this.setState({
|
||||||
|
selectedRows: [],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSelectRows = rows => {
|
||||||
|
this.setState({
|
||||||
|
selectedRows: rows,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSearch = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
|
||||||
|
form.validateFields((err, fieldsValue) => {
|
||||||
|
if (err) return;
|
||||||
|
|
||||||
|
const values = {
|
||||||
|
...fieldsValue,
|
||||||
|
updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
formValues: values,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: 'rule/fetch',
|
||||||
|
payload: values,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleModalVisible = flag => {
|
||||||
|
this.setState({
|
||||||
|
modalVisible: !!flag,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleUpdateModalVisible = (flag, record) => {
|
||||||
|
this.setState({
|
||||||
|
updateModalVisible: !!flag,
|
||||||
|
updateFormValues: record || {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleAdd = fields => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'pipeline/add',
|
||||||
|
payload: {
|
||||||
|
name: fields.name,
|
||||||
|
desc: fields.desc,
|
||||||
|
processors: fields.processors,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('添加成功');
|
||||||
|
this.handleModalVisible();
|
||||||
|
};
|
||||||
|
|
||||||
|
handleUpdate = fields => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'pipeline/update',
|
||||||
|
payload: {
|
||||||
|
name: fields.name,
|
||||||
|
desc: fields.desc,
|
||||||
|
processors: fields.processors,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('修改成功');
|
||||||
|
this.handleUpdateModalVisible();
|
||||||
|
};
|
||||||
|
|
||||||
|
renderSimpleForm() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
} = this.props;
|
||||||
|
return (
|
||||||
|
<Form onSubmit={this.handleSearch} layout="inline">
|
||||||
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
|
<Col md={8} sm={24}>
|
||||||
|
<FormItem label="索引名称">
|
||||||
|
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={8} sm={24}>
|
||||||
|
<span className={styles.submitButtons}>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
查询
|
||||||
|
</Button>
|
||||||
|
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
|
||||||
|
重置
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
return this.renderSimpleForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const data = {
|
||||||
|
list: JSON.parse(this.datasource),
|
||||||
|
pagination: {
|
||||||
|
pageSize: 5,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const { selectedRows, modalVisible, updateModalVisible, updateFormValues,editingIndex, drawerVisible } = this.state;
|
||||||
|
const parentMethods = {
|
||||||
|
handleAdd: this.handleAdd,
|
||||||
|
handleModalVisible: this.handleModalVisible,
|
||||||
|
};
|
||||||
|
const updateMethods = {
|
||||||
|
handleUpdateModalVisible: this.handleUpdateModalVisible,
|
||||||
|
handleUpdate: this.handleUpdate,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Card bordered={false}>
|
||||||
|
<div className={styles.tableList}>
|
||||||
|
<div className={styles.tableListForm}>{this.renderForm()}</div>
|
||||||
|
<div className={styles.tableListOperator}>
|
||||||
|
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
{selectedRows.length > 0 && (
|
||||||
|
<span>
|
||||||
|
<Button onClick={() => this.handleDeleteClick()}>删除</Button>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<StandardTable
|
||||||
|
selectedRows={selectedRows}
|
||||||
|
data={data}
|
||||||
|
columns={this.columns}
|
||||||
|
onSelectRow={this.handleSelectRows}
|
||||||
|
onChange={this.handleStandardTableChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<CreateForm {...parentMethods} modalVisible={modalVisible} />
|
||||||
|
{updateFormValues && Object.keys(updateFormValues).length ? (
|
||||||
|
<UpdateForm
|
||||||
|
{...updateMethods}
|
||||||
|
updateModalVisible={updateModalVisible}
|
||||||
|
values={updateFormValues}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
<Drawer title={editingIndex.index}
|
||||||
|
visible={drawerVisible}
|
||||||
|
onClose={()=>{
|
||||||
|
this.setState({
|
||||||
|
drawerVisible: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
width={640}
|
||||||
|
>
|
||||||
|
<Tabs defaultActiveKey="1" onChange={()=>{}}>
|
||||||
|
<TabPane tab="Summary" key="1">
|
||||||
|
<Descriptions title="General" column={2}>
|
||||||
|
<Descriptions.Item label="Health">green</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Status">open</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Primaries">1</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Replicas">0</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Docs Count">5</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Docs Deleted">0</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Storage Size">115.3kb</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Primary Storage Size"></Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Alias">
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane tab="Mappings" key="2">
|
||||||
|
<JSONWrapper>
|
||||||
|
<JSONPretty json={JSON.parse(`{
|
||||||
|
"mappings": {
|
||||||
|
"_doc": {
|
||||||
|
"dynamic": "strict",
|
||||||
|
"_meta": {
|
||||||
|
"migrationMappingPropertyHashes": {
|
||||||
|
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
|
||||||
|
"originId": "2f4316de49999235636386fe51dc06c1",
|
||||||
|
"task": "235412e52d09e7165fac8a67a43ad6b4",
|
||||||
|
"updated_at": "00da57df13e94e9d98437d13ace4bfe0",
|
||||||
|
"references": "7997cf5a56cc02bdc9c93361bde732b0",
|
||||||
|
"namespace": "2f4316de49999235636386fe51dc06c1",
|
||||||
|
"type": "2f4316de49999235636386fe51dc06c1",
|
||||||
|
"namespaces": "2f4316de49999235636386fe51dc06c1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"migrationVersion": {
|
||||||
|
"dynamic": "true",
|
||||||
|
"properties": {
|
||||||
|
"task": {
|
||||||
|
"type": "text",
|
||||||
|
"fields": {
|
||||||
|
"keyword": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"namespace": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"namespaces": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"originId": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"references": {
|
||||||
|
"type": "nested",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "keyword"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"task": {
|
||||||
|
"properties": {
|
||||||
|
"attempts": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"ownerId": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"retryAt": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"runAt": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"schedule": {
|
||||||
|
"properties": {
|
||||||
|
"interval": {
|
||||||
|
"type": "keyword"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scheduledAt": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"startedAt": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"taskType": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "keyword"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
`)} theme={{
|
||||||
|
background: '#F5F7FA',
|
||||||
|
brace: '#343741',
|
||||||
|
keyQuotes: '#343741',
|
||||||
|
valueQuotes: '#343741',
|
||||||
|
colon: '#343741',
|
||||||
|
comma: '#343741',
|
||||||
|
key: '#343741',
|
||||||
|
value: {
|
||||||
|
string: '#343741',
|
||||||
|
null: '#343741',
|
||||||
|
number: '#343741',
|
||||||
|
boolean: '#343741',
|
||||||
|
},
|
||||||
|
bracket: '#343741',
|
||||||
|
}} /></JSONWrapper>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane tab="Stats" key="3">
|
||||||
|
Content of Tab Pane 3
|
||||||
|
</TabPane>
|
||||||
|
<TabPane tab="Edit settings" key="4">
|
||||||
|
Content of Tab Pane 3
|
||||||
|
</TabPane>
|
||||||
|
</Tabs>
|
||||||
|
<div style={{position:'absolute', bottom: 10}}>
|
||||||
|
<Dropdown
|
||||||
|
placement="topLeft"
|
||||||
|
overlay={(
|
||||||
|
<Menu onClick={()=>{}}>
|
||||||
|
<Menu.Item key="1">
|
||||||
|
<Icon type="delete" />
|
||||||
|
Delete
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item key="2">
|
||||||
|
<Icon type="edit" />
|
||||||
|
Edit
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item key="3">
|
||||||
|
<Icon type="close" />
|
||||||
|
Close
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
)}>
|
||||||
|
<Button type="primary">
|
||||||
|
Manage <Icon type="up" />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
</Drawer>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Index;
|
|
@ -1,141 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'dva';
|
|
||||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
|
||||||
import { Col, Form, Row,Select, Input, Card,Icon,List, Descriptions } from 'antd';
|
|
||||||
|
|
||||||
const {Option} = Select;
|
|
||||||
|
|
||||||
@Form.create()
|
|
||||||
class Query extends React.Component {
|
|
||||||
state={
|
|
||||||
bodyDisplay: 'none',
|
|
||||||
data: [{
|
|
||||||
index: 'blogs-001',
|
|
||||||
id: 'dpOsA3YBCjFOm54VZoNF',
|
|
||||||
source: `{
|
|
||||||
"title" : "elastic search test title",
|
|
||||||
"content": "如默认结构不满足需求,可以自定义该模板,但是自定义模板时必须包含各个 dom 节点的 class,样式可以自定义。",
|
|
||||||
"created_at" : "2020-11-23"
|
|
||||||
}`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 'blogs-002',
|
|
||||||
id: "dpOsA3YBCjFOm54VZoNB",
|
|
||||||
source: `{
|
|
||||||
"title" : "elastic search test title",
|
|
||||||
"created_at" : "2020-11-23",
|
|
||||||
"content": "如默认结构不满足需求,可以自定义该模板,但是自定义模板时必须包含各个 dom 节点的 class,样式可以自定义。"
|
|
||||||
}`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 'blogs-002',
|
|
||||||
id: "dpOsA3YBCjFOm54VZoNC",
|
|
||||||
source: `{
|
|
||||||
"title" : "elastic search test title",
|
|
||||||
"created_at" : "2020-11-23",
|
|
||||||
"content":"如默认结构不满足需求,可以自定义该模板,但是自定义模板时必须包含各个 dom 节点的 class,样式可以自定义。"
|
|
||||||
}`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 'blogs-001',
|
|
||||||
id:"dpOsA3YBCjFOm54VZoNG",
|
|
||||||
source: `{
|
|
||||||
"title" : "elastic search test title",
|
|
||||||
"content":"如默认结构不满足需求,可以自定义该模板,但是自定义模板时必须包含各个 dom 节点的 class,样式可以自定义。",
|
|
||||||
"created_at" : "2020-11-23"
|
|
||||||
}`
|
|
||||||
}, {
|
|
||||||
index: 'blogs-001',
|
|
||||||
id:"dpOsA3YBCjFOm54VZoNG",
|
|
||||||
source: `{
|
|
||||||
"title" : "elastic search test title",
|
|
||||||
"content":"如默认结构不满足需求,可以自定义该模板,但是自定义模板时必须包含各个 dom 节点的 class,样式可以自定义。",
|
|
||||||
"created_at" : "2020-11-23"
|
|
||||||
}`
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
// const {getFieldDecorator} = this.props.form;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Card>
|
|
||||||
<Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
|
|
||||||
<Col span={20}>
|
|
||||||
<Input.Group compact>
|
|
||||||
<Select
|
|
||||||
defaultValue="GET"
|
|
||||||
style={{ width: 80 }}
|
|
||||||
>
|
|
||||||
<Option value="GET">GET</Option>
|
|
||||||
<Option value="POST">POST</Option>
|
|
||||||
<Option value="PUT">PUT</Option>
|
|
||||||
</Select>
|
|
||||||
<Input.Search
|
|
||||||
style={{width:"80%"}}
|
|
||||||
placeholder="input query url"
|
|
||||||
enterButton="execute"
|
|
||||||
onSearch={value => console.log(value)}
|
|
||||||
/>
|
|
||||||
</Input.Group>
|
|
||||||
</Col>
|
|
||||||
<Col span={4}>
|
|
||||||
<a style={{marginTop:5,display:'block'}} onClick={(e)=>{
|
|
||||||
this.setState((preState)=>{
|
|
||||||
if(preState.bodyDisplay == 'none') {
|
|
||||||
return {
|
|
||||||
bodyDisplay: 'block',
|
|
||||||
};
|
|
||||||
}else{
|
|
||||||
return {
|
|
||||||
bodyDisplay: 'none'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}>{this.state.bodyDisplay == 'none' ? '展开':'收起'}<Icon type="down" /></a>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row style={{display: this.state.bodyDisplay}} gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
|
|
||||||
<Col span={20}>
|
|
||||||
<Input.TextArea placeholder="query body" rows={8}/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<List
|
|
||||||
grid={{ gutter: 16, column: 2}}
|
|
||||||
dataSource={this.state.data}
|
|
||||||
pagination={{
|
|
||||||
onChange: page => {
|
|
||||||
console.log(page);
|
|
||||||
},
|
|
||||||
pageSize: 4,
|
|
||||||
total: 50
|
|
||||||
}}
|
|
||||||
renderItem={item => (
|
|
||||||
<List.Item>
|
|
||||||
<Card title={`${item.index} ${item.id}`}
|
|
||||||
extra={<a onClick={()=>{}}>More</a>}
|
|
||||||
actions={[
|
|
||||||
<Icon type="edit" key="edit" onClick={(e)=>{}} />,
|
|
||||||
<Icon type="delete" key="delete" />,
|
|
||||||
]}>
|
|
||||||
<Descriptions bordered column={1}>
|
|
||||||
{/* <Descriptions.Item label="ID">
|
|
||||||
{item.id}
|
|
||||||
</Descriptions.Item> */}
|
|
||||||
<Descriptions.Item label="Source">
|
|
||||||
{item.source}
|
|
||||||
</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
</Card>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Query;
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
import {getDocList, saveDoc, deleteDoc, addDoc} from '@/services/doc';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
|
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];
|
||||||
|
doc[key] = JSON.stringify(doc[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeObjectField(doc){
|
||||||
|
for(let key of Object.keys(doc)){
|
||||||
|
if(['[', '{'].includes(doc[key][0])){
|
||||||
|
try{
|
||||||
|
doc[key] = JSON.parse(doc[key])
|
||||||
|
}catch(e){
|
||||||
|
message.warn(key +': json format error');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespace: "document",
|
||||||
|
state: {
|
||||||
|
index: '',
|
||||||
|
editingKey: '',
|
||||||
|
isLoading: false,
|
||||||
|
},
|
||||||
|
effects: {
|
||||||
|
*fetchDocList({payload}, {call, put}){
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let res = yield call(getDocList, payload);
|
||||||
|
if(res.errno != "0"){
|
||||||
|
message.warn("加载数据失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let indices = [];
|
||||||
|
if(res.payload.data && res.payload.data.length > 0){
|
||||||
|
for(let doc of res.payload.data){
|
||||||
|
if(!indices.includes(doc._index)){
|
||||||
|
indices.push(doc._index);
|
||||||
|
}
|
||||||
|
encodeObjectField(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
pageIndex: payload.pageIndex,
|
||||||
|
pageSize: payload.pageSize,
|
||||||
|
isLoading: false,
|
||||||
|
index: payload.index,
|
||||||
|
indices,
|
||||||
|
cluster: payload.cluster || '',
|
||||||
|
filter: payload.filter || '',
|
||||||
|
...res.payload,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*saveDocItem({payload}, {call, put, select}){
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let doc = payload.data;
|
||||||
|
//let {rawData} = yield select(state => state.document);
|
||||||
|
if(decodeObjectField(doc) === false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let res = yield call(saveDoc, payload);
|
||||||
|
if(res.errno != "0"){
|
||||||
|
message.warn("保存数据失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
encodeObjectField(doc);
|
||||||
|
yield put({
|
||||||
|
type: '_saveDocItem',
|
||||||
|
payload: {
|
||||||
|
docItem: payload.data,
|
||||||
|
extra: {
|
||||||
|
editingKey: '',
|
||||||
|
isLoading: false,
|
||||||
|
_index: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*deleteDocItem({payload}, {call, put}){
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let res = yield call(deleteDoc, payload);
|
||||||
|
if(res.errno != "0"){
|
||||||
|
message.warn("删除数据失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
yield put({
|
||||||
|
type: '_deleteDocItem',
|
||||||
|
payload: {
|
||||||
|
docItem: payload.data,
|
||||||
|
extra: {
|
||||||
|
isLoading: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*addDocItem({payload},{call, put}){
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(decodeObjectField(payload.data) === false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let res = yield call(addDoc, payload);
|
||||||
|
if(res.errno != "0"){
|
||||||
|
message.warn("添加文档失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
encodeObjectField(res.payload);
|
||||||
|
yield put({
|
||||||
|
type: '_addNew',
|
||||||
|
payload: {
|
||||||
|
docItem: res.payload,
|
||||||
|
extra: {
|
||||||
|
isLoading: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
saveData(state, {payload}){
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_saveDocItem(state, {payload}){
|
||||||
|
let idx = state.data.findIndex((item) => {
|
||||||
|
return item.id == payload.docItem.id;
|
||||||
|
});
|
||||||
|
idx > -1 && (state.data[idx] = {
|
||||||
|
...state.data[idx],
|
||||||
|
...payload.docItem,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_deleteDocItem(state, {payload}){
|
||||||
|
let idx = state.data.findIndex((item) => {
|
||||||
|
return item.id == payload.docItem.id;
|
||||||
|
});
|
||||||
|
state.data.splice(idx, 1);
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_addNew(state, {payload}){
|
||||||
|
if(payload.extra && payload.extra.isAddNew){
|
||||||
|
state.data.unshift(payload.docItem)
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra,
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
state.data[0] = payload.docItem;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancelNew(state,{payload}){
|
||||||
|
state.data.shift()
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isAddNew: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ const UpdateForm = Form.create()(props => {
|
||||||
form.validateFields((err, fieldsValue) => {
|
form.validateFields((err, fieldsValue) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
let upVals = Object.assign(values, fieldsValue);
|
let upVals = Object.assign(_.cloneDeep(values), fieldsValue);
|
||||||
handleUpdate(upVals);
|
handleUpdate(upVals);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -69,33 +69,22 @@ class Pro extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleUpdate = this.handleUpdate.bind(this);
|
this.handleUpdate = this.handleUpdate.bind(this);
|
||||||
}
|
}
|
||||||
state = {
|
|
||||||
updateFormValues: null,
|
|
||||||
currentFormOp: null,
|
|
||||||
data: [],
|
|
||||||
search: {
|
|
||||||
size: 6,
|
|
||||||
name: "",
|
|
||||||
tags: "",
|
|
||||||
pageIndex: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
this.fetchData();
|
const {size} = this.props.dict.search;
|
||||||
|
this.fetchData({
|
||||||
|
from: 0,
|
||||||
|
size: size,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReset = ()=>{
|
handleReset = ()=>{
|
||||||
const {form} = this.props;
|
const {form} = this.props;
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
this.setState({
|
this.fetchData({
|
||||||
search: {
|
from: 0,
|
||||||
size: 6,
|
size: this.props.dict.search.size,
|
||||||
name: "",
|
name: '',
|
||||||
tags: "",
|
tags: ''
|
||||||
pageIndex: 1,
|
|
||||||
}
|
|
||||||
},()=>{
|
|
||||||
this.fetchData();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,14 +93,12 @@ class Pro extends React.Component {
|
||||||
let me = this;
|
let me = this;
|
||||||
form.validateFields((err, fieldsValue) => {
|
form.validateFields((err, fieldsValue) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
me.setState({search:{
|
me.fetchData({
|
||||||
...me.state.search,
|
form: 0,
|
||||||
pageIndex: 1,
|
size: me.props.dict.search.size,
|
||||||
name: fieldsValue.name,
|
name: fieldsValue.name,
|
||||||
tags: fieldsValue.tags.join(',')
|
tags: fieldsValue.tags.join(',')
|
||||||
}},()=>{
|
})
|
||||||
me.fetchData();
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,18 +148,24 @@ class Pro extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
handleNewClick = () => {
|
handleNewClick = () => {
|
||||||
this.setState({
|
const {dispatch} = this.props;
|
||||||
currentFormOp: 'NEW',
|
dispatch({
|
||||||
updateFormValues: {},
|
type: 'dict/saveData',
|
||||||
formTitle: '添加词典'
|
payload: {
|
||||||
|
currentFormOp: 'NEW',
|
||||||
|
updateFormValues: {},
|
||||||
|
formTitle: '添加词典'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDelete = (item) =>{
|
handleDelete = (item) =>{
|
||||||
const {dispatch} = this.props;
|
const {dispatch, dict} = this.props;
|
||||||
|
const search = dict.search;
|
||||||
|
const me = this;
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '删除Pipeline',
|
title: '删除词典',
|
||||||
content: '确定删除该Pipeline吗?',
|
content: '确定删除该词典吗?',
|
||||||
okText: '确认',
|
okText: '确认',
|
||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
|
@ -188,15 +181,19 @@ class Pro extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleModifyClick = (item)=>{
|
handleModifyClick = (item)=>{
|
||||||
this.setState({
|
const {dispatch} = this.props;
|
||||||
updateFormValues: item,
|
dispatch({
|
||||||
formTitle: '修改词典',
|
type: 'dict/saveData',
|
||||||
currentFormOp: 'UPDATE',
|
payload: {
|
||||||
})
|
updateFormValues: item,
|
||||||
|
formTitle: '修改词典',
|
||||||
|
currentFormOp: 'UPDATE',
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpdate(values){
|
handleUpdate(values){
|
||||||
let {currentFormOp, data} = this.state;
|
let {currentFormOp} = this.props.dict;
|
||||||
const {dispatch} = this.props;
|
const {dispatch} = this.props;
|
||||||
let me = this;
|
let me = this;
|
||||||
switch(currentFormOp){
|
switch(currentFormOp){
|
||||||
|
@ -204,69 +201,51 @@ class Pro extends React.Component {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'dict/addDictItem',
|
type: 'dict/addDictItem',
|
||||||
payload: values,
|
payload: values,
|
||||||
callback: ()=>{
|
|
||||||
me.setState({
|
|
||||||
updateFormValues: null,
|
|
||||||
currentFormOp: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "UPDATE":
|
case "UPDATE":
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'dict/updateDictItem',
|
type: 'dict/updateDictItem',
|
||||||
payload: values,
|
payload: values,
|
||||||
callback: ()=>{
|
|
||||||
me.setState({
|
|
||||||
updateFormValues: null,
|
|
||||||
currentFormOp: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData = ()=>{
|
fetchData = (params)=>{
|
||||||
const {dispatch} = this.props;
|
const {dispatch} = this.props;
|
||||||
let {size, pageIndex} = this.state.search;
|
|
||||||
let me = this;
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'dict/fetchDictList',
|
type: 'dict/fetchDictList',
|
||||||
payload: {
|
payload: params
|
||||||
from: (pageIndex - 1) * size,
|
|
||||||
...this.state.search
|
|
||||||
},
|
|
||||||
callback: ()=>{
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePageChange = (p)=>{
|
handlePageChange = (p)=>{
|
||||||
this.setState({
|
let search = this.props.dict.search;
|
||||||
search: {
|
|
||||||
...this.state.search,
|
this.fetchData({
|
||||||
pageIndex: p,
|
...search,
|
||||||
}
|
from: (p-1) * search.size,
|
||||||
},()=>{
|
pageIndex: p,
|
||||||
this.fetchData();
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
let data = this.props.dict ? this.props.dict.dictList : [];
|
//console.log('render');
|
||||||
let total = this.props.dict ? this.props.dict.total: 0;
|
let {dictList, search, updateFormValues, total, formTitle} = this.props.dict;
|
||||||
let updateFormValues = this.state.updateFormValues;
|
let {pageIndex, size} = search;
|
||||||
let size = this.state.search.size;
|
const {dispatch} = this.props;
|
||||||
const updateMethods = {
|
const updateMethods = {
|
||||||
handleUpdate: this.handleUpdate,
|
handleUpdate: this.handleUpdate,
|
||||||
handleUpdateModalVisible: ()=>{
|
handleUpdateModalVisible: ()=>{
|
||||||
this.setState({
|
dispatch({
|
||||||
updateFormValues: null,
|
type:'dict/saveData',
|
||||||
currentFormOp: null,
|
payload: {
|
||||||
})
|
updateFormValues: null,
|
||||||
|
currentFormOp: null,
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
console.log('render');
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Card bordered={false} bodyStyle={{paddingBottom:0}} >
|
<Card bordered={false} bodyStyle={{paddingBottom:0}} >
|
||||||
|
@ -278,11 +257,11 @@ class Pro extends React.Component {
|
||||||
bordered={false}>
|
bordered={false}>
|
||||||
<List
|
<List
|
||||||
className="dic-list"
|
className="dic-list"
|
||||||
dataSource={data}
|
dataSource={dictList}
|
||||||
pagination={{
|
pagination={{
|
||||||
pageSize: size,
|
pageSize: size,
|
||||||
total: total,
|
total: total,
|
||||||
current: this.state.search.pageIndex,
|
current: pageIndex,
|
||||||
onChange: this.handlePageChange
|
onChange: this.handlePageChange
|
||||||
}}
|
}}
|
||||||
grid={{
|
grid={{
|
||||||
|
@ -320,7 +299,7 @@ class Pro extends React.Component {
|
||||||
</Card>
|
</Card>
|
||||||
{updateFormValues ? (
|
{updateFormValues ? (
|
||||||
<UpdateForm
|
<UpdateForm
|
||||||
title={this.state.formTitle}
|
title={formTitle}
|
||||||
{...updateMethods}
|
{...updateMethods}
|
||||||
values={updateFormValues}
|
values={updateFormValues}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -50,9 +50,18 @@ export default {
|
||||||
namespace: 'dict',
|
namespace: 'dict',
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
|
updateFormValues: null,
|
||||||
|
currentFormOp: null,
|
||||||
|
formTitle: '',
|
||||||
|
search: {
|
||||||
|
size: 6,
|
||||||
|
name: "",
|
||||||
|
tags: "",
|
||||||
|
pageIndex: 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
effects: {
|
effects: {
|
||||||
*fetchDictList({payload, callback}, {call, put}){
|
*fetchDictList({payload}, {call, put}){
|
||||||
const resp = yield call(getDictList, payload);
|
const resp = yield call(getDictList, payload);
|
||||||
if(resp.errno != "0" || !resp.data.Result){
|
if(resp.errno != "0" || !resp.data.Result){
|
||||||
return
|
return
|
||||||
|
@ -61,21 +70,26 @@ export default {
|
||||||
item.content = utf8.decode(atob(item.content))
|
item.content = utf8.decode(atob(item.content))
|
||||||
return item;
|
return item;
|
||||||
})
|
})
|
||||||
|
let search = {name:'', tags: ''};
|
||||||
|
payload.pageIndex = payload.from / payload.size + 1;
|
||||||
|
search = Object.assign(search, payload);
|
||||||
|
|
||||||
yield put({
|
yield put({
|
||||||
type: 'saveData',
|
type: 'saveData',
|
||||||
payload: {
|
payload: {
|
||||||
dictList: resp.data.Result,
|
dictList: resp.data.Result,
|
||||||
total: resp.data.Total,
|
total: resp.data.Total,
|
||||||
...payload,
|
search: search,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if(callback && typeof callback == 'function'){
|
|
||||||
callback(resp);
|
|
||||||
}
|
|
||||||
//message.loading('数据加载完成', 'initdata');
|
//message.loading('数据加载完成', 'initdata');
|
||||||
},
|
},
|
||||||
*addDictItem({payload, callback}, {call, put}){
|
*addDictItem({payload}, {call, put}){
|
||||||
const rel = yield call(addDict, payload);
|
let upVals = {
|
||||||
|
...payload,
|
||||||
|
}
|
||||||
|
upVals.content = btoa(utf8.encode(upVals.content));
|
||||||
|
const rel = yield call(addDict, upVals);
|
||||||
if(rel.errno != "0"){
|
if(rel.errno != "0"){
|
||||||
message.warn('添加失败:'+ rel.errmsg)
|
message.warn('添加失败:'+ rel.errmsg)
|
||||||
return
|
return
|
||||||
|
@ -83,25 +97,34 @@ export default {
|
||||||
rel.payload.content = utf8.decode(atob(rel.payload.content));
|
rel.payload.content = utf8.decode(atob(rel.payload.content));
|
||||||
yield put({
|
yield put({
|
||||||
type: 'addDict',
|
type: 'addDict',
|
||||||
payload: rel.payload,
|
payload: {
|
||||||
|
dictItem: rel.payload,
|
||||||
|
extra: {
|
||||||
|
updateFormValues: null,
|
||||||
|
currentFormOp: null
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if(callback && typeof callback == 'function'){
|
|
||||||
callback(rel);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
*updateDictItem({payload, callback}, {call, put}){
|
*updateDictItem({payload}, {call, put}){
|
||||||
|
let rawContent = payload.content;
|
||||||
|
payload.content = btoa(utf8.encode(payload.content));
|
||||||
const rel = yield call(updateDict, payload);
|
const rel = yield call(updateDict, payload);
|
||||||
if(rel.errno != "0"){
|
if(rel.errno != "0"){
|
||||||
message.warn('修改:'+ rel.errmsg)
|
message.warn('修改:'+ rel.errmsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
payload.content = rawContent;
|
||||||
yield put({
|
yield put({
|
||||||
type: 'updateDict',
|
type: 'updateDict',
|
||||||
payload: payload,
|
payload: {
|
||||||
|
dictItem: payload,
|
||||||
|
extra:{
|
||||||
|
updateFormValues: null,
|
||||||
|
currentFormOp: null
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if(callback && typeof callback == 'function'){
|
|
||||||
callback(rel);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
*deleteDictItem({payload}, {call, put, select}){
|
*deleteDictItem({payload}, {call, put, select}){
|
||||||
let rel = yield call(deleteDict, payload);
|
let rel = yield call(deleteDict, payload);
|
||||||
|
@ -112,14 +135,20 @@ export default {
|
||||||
message.warn('删除失败:'+ rel.errmsg)
|
message.warn('删除失败:'+ rel.errmsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const state = yield select(state => state.dict)
|
|
||||||
yield put({
|
yield put({
|
||||||
type: 'fetchDictList',
|
type:'deleteDict',
|
||||||
payload: {
|
payload: {
|
||||||
from: state.from,
|
dictItem: payload,
|
||||||
size: state.size,
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
//const search = yield select(state => state.dict.search)
|
||||||
|
|
||||||
|
// yield put({
|
||||||
|
// type: 'fetchDictList',
|
||||||
|
// payload: search,
|
||||||
|
// })
|
||||||
|
//yield take('fetchDictList/@@end')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reducers: {
|
reducers: {
|
||||||
|
@ -131,17 +160,35 @@ export default {
|
||||||
},
|
},
|
||||||
addDict(state, {payload}){
|
addDict(state, {payload}){
|
||||||
let dictList = state.dictList || [];
|
let dictList = state.dictList || [];
|
||||||
dictList.unshift(payload);
|
dictList.unshift(payload.dictItem);
|
||||||
state.dictList = dictList;
|
state.dictList = dictList;
|
||||||
return state;
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra,
|
||||||
|
total: state.total + 1,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
updateDict(state, {payload}){
|
updateDict(state, {payload}){
|
||||||
let cdata = state.dictList;
|
let cdata = state.dictList;
|
||||||
let idx = cdata.findIndex((item)=>{
|
let idx = cdata.findIndex((item)=>{
|
||||||
return item.id == payload.id;
|
return item.id == payload.dictItem.id;
|
||||||
})
|
})
|
||||||
idx > -1 && (cdata[idx] = values);
|
idx > -1 && (cdata[idx] = payload.dictItem);
|
||||||
return state;
|
return {
|
||||||
|
...state,
|
||||||
|
...payload.extra,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteDict(state, {payload}){
|
||||||
|
let cdata = state.dictList;
|
||||||
|
let idx = cdata.findIndex((item)=>{
|
||||||
|
return item.id == payload.dictItem.id;
|
||||||
|
})
|
||||||
|
idx > -1 && (state.dictList.splice(idx, 1));
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
total: state.total - 1,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
export async function getDocList(params) {
|
||||||
|
return request(`/api/doc/${params.index}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
action: 'SEARCH',
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveDoc(params) {
|
||||||
|
return request(`/api/doc/${params.index}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
payload: params.data,
|
||||||
|
index: params.index,
|
||||||
|
action: 'SAVE',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteDoc(params) {
|
||||||
|
return request(`/api/doc/${params.index}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
index: params.index,
|
||||||
|
action: 'DELETE',
|
||||||
|
payload: params.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addDoc(params) {
|
||||||
|
return request(`/api/doc/${params.index}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
payload: params.data,
|
||||||
|
index: params.index,
|
||||||
|
action: 'ADD',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue