add discover table view and fixed bugs
This commit is contained in:
parent
947b0bfa04
commit
e1cd6d0cf7
|
@ -21,92 +21,91 @@ type docReqBody struct {
|
|||
}
|
||||
|
||||
func (handler APIHandler) HandleAddDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
reqBody := map[string]interface{}{}
|
||||
resResult := newResponseBody()
|
||||
resBody := newResponseBody()
|
||||
err := handler.DecodeJSON(req, &reqBody)
|
||||
if err != nil {
|
||||
resResult["status"] = false
|
||||
resResult["error"] = err.Error()
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
resBody["error"] = err.Error()
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
indexName := ps.ByName("index")
|
||||
id := ps.ByName("id")
|
||||
if strings.Trim(id, "/") == "" {
|
||||
id = util.GetUUID()
|
||||
docID := ps.ByName("docId")
|
||||
if strings.Trim(docID, "/") == "" {
|
||||
docID = util.GetUUID()
|
||||
}
|
||||
docType := handler.GetParameter(req, "_type")
|
||||
_, err = client.Index(indexName, docType, id, reqBody)
|
||||
insertRes, err := client.Index(indexName, docType, docID, reqBody)
|
||||
if err != nil {
|
||||
resResult["status"] = false
|
||||
resResult["error"] = err
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
reqBody["id"] = id
|
||||
resResult["payload"] = reqBody
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
reqBody["_id"] = docID
|
||||
resBody["result"] = insertRes.Result
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleUpdateDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
resBody := newResponseBody()
|
||||
if client == nil {
|
||||
resBody["error"] = "can not found target cluster"
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
reqBody := map[string]interface{}{}
|
||||
resResult := newResponseBody()
|
||||
|
||||
err := handler.DecodeJSON(req, &reqBody)
|
||||
if err != nil {
|
||||
resResult["status"] = false
|
||||
resResult["error"] = err
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
indexName := ps.ByName("index")
|
||||
id := ps.ByName("id")
|
||||
docID := ps.ByName("docId")
|
||||
typ := handler.GetParameter(req, "_type")
|
||||
resp, err := client.Get(indexName,typ, id)
|
||||
insertRes, err := client.Index(indexName, typ, docID, reqBody)
|
||||
if err != nil {
|
||||
resResult["status"] = false
|
||||
resResult["error"] = err.Error()
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
resBody["error"] = err.Error()
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
source := resp.Source
|
||||
for k, v := range reqBody {
|
||||
if k == "id" {
|
||||
continue
|
||||
}
|
||||
source[k] = v
|
||||
}
|
||||
_, err = client.Index(indexName, typ, id, source)
|
||||
if err != nil {
|
||||
resResult["status"] = false
|
||||
resResult["error"] = err.Error()
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resResult["payload"] = reqBody
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
resBody["_source"] = reqBody
|
||||
resBody["_id"] = docID
|
||||
resBody["result"] = insertRes.Result
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleDeleteDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
resResult := newResponseBody()
|
||||
indexName := ps.ByName("index")
|
||||
id := ps.ByName("id")
|
||||
typ := handler.GetParameter(req, "_type")
|
||||
_, err := client.Delete(indexName, typ, id)
|
||||
if err != nil {
|
||||
resResult["error"] = err.Error()
|
||||
resResult["status"] = false
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
resBody := newResponseBody()
|
||||
if client == nil {
|
||||
resBody["error"] = "can not found target cluster"
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resResult["payload"] = true
|
||||
handler.WriteJSON(w, resResult, http.StatusOK)
|
||||
|
||||
indexName := ps.ByName("index")
|
||||
docID := ps.ByName("docId")
|
||||
typ := handler.GetParameter(req, "_type")
|
||||
delRes, err := client.Delete(indexName, typ, docID, "wait_for")
|
||||
if err != nil {
|
||||
resBody["error"] = err.Error()
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["result"] = delRes.Result
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleSearchDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
reqBody := docReqBody{}
|
||||
resResult := newResponseBody()
|
||||
err := handler.DecodeJSON(req, &reqBody)
|
||||
|
|
|
@ -2,13 +2,13 @@ package index_management
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/cihub/seelog"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/elastic"
|
||||
"infini.sh/framework/core/orm"
|
||||
"infini.sh/framework/core/util"
|
||||
"infini.sh/framework/modules/elastic/common"
|
||||
"net/http"
|
||||
log "github.com/cihub/seelog"
|
||||
)
|
||||
|
||||
func (handler APIHandler) ElasticsearchOverviewAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
|
@ -49,6 +49,7 @@ func (handler APIHandler) ElasticsearchOverviewAction(w http.ResponseWriter, req
|
|||
}
|
||||
return true
|
||||
})
|
||||
|
||||
resBody := util.MapStr{
|
||||
"total_node": totalNode,
|
||||
"total_store_size_in_bytes": totalStoreSize,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package index_management
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/elastic"
|
||||
"infini.sh/framework/core/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (handler APIHandler) HandleGetMappingsAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
indexName := ps.ByName("index")
|
||||
resBody := newResponseBody()
|
||||
var copyAll = false
|
||||
|
@ -20,114 +20,102 @@ func (handler APIHandler) HandleGetMappingsAction(w http.ResponseWriter, req *ht
|
|||
_, _, idxs, err := client.GetMapping(copyAll, indexName)
|
||||
if err != nil {
|
||||
resBody["error"] = err
|
||||
resBody["status"] = false
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
if copyAll {
|
||||
for key, _ := range *idxs {
|
||||
if strings.HasPrefix(key, ".") || strings.HasPrefix(key, "infini-") {
|
||||
delete(*idxs, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
//if copyAll {
|
||||
// for key, _ := range *idxs {
|
||||
// if strings.HasPrefix(key, ".") || strings.HasPrefix(key, "infini-") {
|
||||
// delete(*idxs, key)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
resBody["payload"] = idxs
|
||||
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
handler.WriteJSON(w, idxs, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleGetIndicesAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
catIndices, err := client.GetIndices("")
|
||||
for key, _ := range *catIndices {
|
||||
if strings.HasPrefix(key,".") || strings.HasPrefix(key, "infini-"){
|
||||
delete(*catIndices, key)
|
||||
}
|
||||
}
|
||||
resBody := newResponseBody()
|
||||
resBody := util.MapStr{}
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["payload"] = catIndices
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
handler.WriteJSON(w, catIndices, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleGetSettingsAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
indexName := ps.ByName("index")
|
||||
resBody := newResponseBody()
|
||||
indexes, err := client.GetIndexSettings(indexName)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["payload"] = indexes
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
handler.WriteJSON(w, indexes, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleUpdateSettingsAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
indexName := ps.ByName("index")
|
||||
settings := map[string]interface{}{}
|
||||
resBody := newResponseBody()
|
||||
err := handler.DecodeJSON(req, &settings)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
err = client.UpdateIndexSettings(indexName, settings)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["payload"] = true
|
||||
resBody["result"] = "updated"
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleDeleteIndexAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
indexName := ps.ByName("index")
|
||||
resBody := newResponseBody()
|
||||
err := client.DeleteIndex(indexName)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["payload"] = true
|
||||
resBody["result"] = "deleted"
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (handler APIHandler) HandleCreateIndexAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||
targetClusterID := ps.ByName("id")
|
||||
client := elastic.GetClient(targetClusterID)
|
||||
indexName := ps.ByName("index")
|
||||
resBody := newResponseBody()
|
||||
config := map[string]interface{}{}
|
||||
err := handler.DecodeJSON(req, &config)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
err = client.CreateIndex(indexName, config)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["payload"] = true
|
||||
resBody["result"] = "created"
|
||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
|
22
api/init.go
22
api/init.go
|
@ -16,6 +16,7 @@ func Init(cfg *config.AppConfig) {
|
|||
Config: cfg,
|
||||
}
|
||||
var pathPrefix = "/_search-center/"
|
||||
var esPrefix = "/elasticsearch/:id/"
|
||||
//ui.HandleUIMethod(api.POST, "/api/get_indices",index_management.API1)
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/overview"), handler.ElasticsearchOverviewAction)
|
||||
|
||||
|
@ -24,20 +25,21 @@ func Init(cfg *config.AppConfig) {
|
|||
//ui.HandleUIMethod(api.GET, "/api/dict/:id",handler.GetDictItemAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "dict/:id"), handler.DeleteDictItemAction)
|
||||
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix, "dict/:id"), handler.UpdateDictItemAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "doc/:index/_search"), handler.HandleSearchDocumentAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "doc/:index/_create"), handler.HandleAddDocumentAction)
|
||||
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix, "doc/:index/:id"), handler.HandleUpdateDocumentAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "doc/:index/:id"), handler.HandleDeleteDocumentAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "doc/:index/_search"), handler.HandleSearchDocumentAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "doc/:index"), handler.HandleAddDocumentAction)
|
||||
ui.HandleUIMethod(api.PUT, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleUpdateDocumentAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleDeleteDocumentAction)
|
||||
|
||||
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "rebuild/*id"), handler.HandleReindexAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "rebuild/_search"), handler.HandleGetRebuildListAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "rebuild/:id"), handler.HandleDeleteRebuildAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "_cat/indices"), handler.HandleGetIndicesAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "index/:index/_mappings"), handler.HandleGetMappingsAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "index/:index/_settings"), handler.HandleGetSettingsAction)
|
||||
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix, "index/:index/_settings"), handler.HandleUpdateSettingsAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "index/:index"), handler.HandleDeleteIndexAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "index/:index"), handler.HandleCreateIndexAction)
|
||||
|
||||
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "_cat/indices"), handler.HandleGetIndicesAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "index/:index/_mappings"), handler.HandleGetMappingsAction)
|
||||
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "index/:index/_settings"), handler.HandleGetSettingsAction)
|
||||
ui.HandleUIMethod(api.PUT, path.Join(esPrefix, "index/:index/_settings"), handler.HandleUpdateSettingsAction)
|
||||
ui.HandleUIMethod(api.DELETE, path.Join(esPrefix, "index/:index"), handler.HandleDeleteIndexAction)
|
||||
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "index/:index"), handler.HandleCreateIndexAction)
|
||||
|
||||
//new api
|
||||
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "alerting/overview"), alerting.GetAlertOverview)
|
||||
|
|
|
@ -139,25 +139,6 @@ export default [
|
|||
name: 'data',
|
||||
icon: 'database',
|
||||
routes: [
|
||||
// {
|
||||
// path: '/data/pipes',
|
||||
// name: 'pipes',
|
||||
// component: './DataManagement/Pipes',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/data/pipes',
|
||||
// redirect: '/data/pipes/logstash',
|
||||
// },
|
||||
// {
|
||||
// path: '/data/pipes/logstash',
|
||||
// component: './DataManagement/LogstashConfig',
|
||||
// },
|
||||
// {
|
||||
// path: '/data/pipes/ingestpipeline',
|
||||
// component: './DataManagement/IngestPipeline',
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// path: '/data/overview',
|
||||
// name: 'overview',
|
||||
|
@ -165,14 +146,16 @@ export default [
|
|||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// }, {
|
||||
// path: '/data/index',
|
||||
// name: 'index',
|
||||
// component: './DataManagement/Index',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// },{
|
||||
// },
|
||||
{
|
||||
path: '/data/index',
|
||||
name: 'index',
|
||||
component: './DataManagement/Index',
|
||||
routes:[
|
||||
{ path: '/', redirect: '/' },
|
||||
],
|
||||
},
|
||||
// {
|
||||
// path: '/data/document',
|
||||
// name: 'document',
|
||||
// component: './DataManagement/Document',
|
||||
|
@ -269,9 +252,9 @@ export default [
|
|||
// {
|
||||
// path: '/search/alias',
|
||||
// redirect: '/search/alias/index',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// },
|
||||
// {
|
||||
// path: '/search/alias/index',
|
||||
|
@ -296,9 +279,9 @@ export default [
|
|||
// {
|
||||
// path: '/search/dict',
|
||||
// redirect: '/search/dict/professional',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// },
|
||||
// {
|
||||
// path: '/search/dict/professional',
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
"@babel/runtime": "^7.1.2",
|
||||
"@elastic/charts": "^25.0.1",
|
||||
"@elastic/datemath": "^5.0.3",
|
||||
"@elastic/eui": "^34.4.0",
|
||||
"@elastic/eui": "34.4.0",
|
||||
"@elastic/numeral": "^2.5.1",
|
||||
"@hapi/boom": "^9.1.3",
|
||||
"@monaco-editor/react": "^3.7.4",
|
||||
"@monaco-editor/react": "^4.2.2",
|
||||
"@svgdotjs/svg.js": "^3.0.16",
|
||||
"antd": "^3.26.18",
|
||||
"antd-table-infinity": "^1.1.6",
|
||||
|
|
|
@ -57,7 +57,7 @@ interface SavedObjectBody {
|
|||
type FormatFieldFn = (hit: Record<string, any>, fieldName: string) => any;
|
||||
|
||||
export class IndexPattern implements IIndexPattern {
|
||||
public id?: string;
|
||||
public id: string;
|
||||
public title: string = '';
|
||||
public viewName: string = '';
|
||||
public fieldFormatMap: Record<string, any>;
|
||||
|
|
|
@ -174,7 +174,7 @@ export interface FieldSpec {
|
|||
export type IndexPatternFieldMap = Record<string, FieldSpec>;
|
||||
|
||||
export interface IndexPatternSpec {
|
||||
id?: string;
|
||||
id: string;
|
||||
version?: string;
|
||||
title?: string;
|
||||
intervalName?: string;
|
||||
|
|
|
@ -15,12 +15,14 @@ interface TableProps {
|
|||
onChangeSortOrder?: (sortOrder: SortOrder[]) => void;
|
||||
onMoveColumn?: (name: string, index: number) => void;
|
||||
onRemoveColumn?: (name: string) => void;
|
||||
onAddColumn?: (name: string) => void;
|
||||
document: any;
|
||||
}
|
||||
|
||||
const pageCount = 50;
|
||||
|
||||
const Table: React.FC<TableProps> = ({ columns, hits, sortOrder, indexPattern, onFilter, onMoveColumn,
|
||||
onRemoveColumn, onChangeSortOrder }) => {
|
||||
const Table: React.FC<TableProps> = ({ columns, hits, sortOrder, indexPattern, onFilter, onMoveColumn, onAddColumn,
|
||||
onRemoveColumn, onChangeSortOrder, document }) => {
|
||||
const [scrollState, setScrollState] = useState({limit: pageCount, hasMore: true});
|
||||
useEffect(()=>{
|
||||
setScrollState({
|
||||
|
@ -46,7 +48,7 @@ const Table: React.FC<TableProps> = ({ columns, hits, sortOrder, indexPattern, o
|
|||
<div>
|
||||
{hits.length ? (
|
||||
<div>
|
||||
<table className="kbn-table table" data-test-subj="docTable">
|
||||
<table className="kbn-table table">
|
||||
<thead>
|
||||
<TableHeader columns={columns}
|
||||
defaultSortOrder={''}
|
||||
|
@ -66,9 +68,10 @@ const Table: React.FC<TableProps> = ({ columns, hits, sortOrder, indexPattern, o
|
|||
hideTimeColumn={false}
|
||||
indexPattern={indexPattern}
|
||||
isShortDots={false}
|
||||
onAddColumn={()=>{}}
|
||||
onRemoveColumn={()=>{}}
|
||||
onAddColumn={onAddColumn}
|
||||
onRemoveColumn={onRemoveColumn}
|
||||
row={row}
|
||||
document={document}
|
||||
/>
|
||||
})}
|
||||
</tbody>
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
import {EuiIcon} from '@elastic/eui';
|
||||
import { DocViewer } from '../../doc_viewer/doc_viewer';
|
||||
import {Drawer, Button, Menu,Dropdown, Icon, Popconfirm, message,Descriptions, Popover, Input} from 'antd';
|
||||
import Editor from "@monaco-editor/react";
|
||||
import {useState, useRef} from 'react';
|
||||
|
||||
function generateNewID(id: string) {
|
||||
return id.slice(0, 14) + Math.random().toString(36).substr(2, 6)
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface Props {
|
||||
columns: string[];
|
||||
|
@ -8,6 +17,7 @@ interface Props {
|
|||
onFilter: (field: any, values: any, operation: any) => void;
|
||||
onAddColumn?: (name: string) => void;
|
||||
onRemoveColumn?: (name: string) => void;
|
||||
document: any;
|
||||
}
|
||||
|
||||
export function Detail({
|
||||
|
@ -17,7 +27,59 @@ export function Detail({
|
|||
onFilter,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
document,
|
||||
}:Props){
|
||||
const [editorVisible, setEditorVisble] = useState(false);
|
||||
const editorRef = useRef(null);
|
||||
|
||||
function handleEditorDidMount(editor, monaco) {
|
||||
editorRef.current = editor;
|
||||
}
|
||||
|
||||
const editDocumentClick = ()=>{
|
||||
setEditorVisble(true)
|
||||
}
|
||||
const editCancelClick = ()=>{
|
||||
setEditorVisble(false)
|
||||
}
|
||||
const saveDocumentClick = async (docID?: string)=>{
|
||||
const value = editorRef.current?.getValue();
|
||||
let source = {}
|
||||
try {
|
||||
source = JSON.parse(value)
|
||||
} catch (error) {
|
||||
message.error('wrong json format')
|
||||
return
|
||||
}
|
||||
const res = await document.saveDocument({
|
||||
_index: row._index,
|
||||
_id: docID || row._id,
|
||||
_type: row._type,
|
||||
_source: source
|
||||
})
|
||||
if(!res.error) setEditorVisble(false)
|
||||
}
|
||||
const deleteDocumentClick = ()=>{
|
||||
document.deleteDocument({
|
||||
_index: row._index,
|
||||
_id: row._id,
|
||||
_type: row._type,
|
||||
})
|
||||
}
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="Edit" onClick={editDocumentClick}>
|
||||
<a> Edit </a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="Delete">
|
||||
<Popconfirm title="sure to delete" onConfirm={()=>{
|
||||
deleteDocumentClick();
|
||||
}}><a> Delete </a></Popconfirm>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<td colSpan={ columns.length + 2 }>
|
||||
<div className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--justifyContentSpaceBetween">
|
||||
|
@ -34,9 +96,49 @@ export function Detail({
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="euiFlexItem euiFlexItem--flexGrowZero euiText euiText--small">
|
||||
<div className="euiFlexItem euiFlexItem--flexGrowZero euiText euiText--small">
|
||||
<div className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow">
|
||||
<Drawer title="Edit document" visible={editorVisible} width="640" destroyOnClose={true}
|
||||
onClose={()=>{setEditorVisble(false)}}>
|
||||
<Descriptions>
|
||||
<Descriptions.Item label="_index">{row._index}</Descriptions.Item>
|
||||
<Descriptions.Item label="_id">{row._id}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Editor
|
||||
height="70vh"
|
||||
theme="vs-light"
|
||||
language="json"
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
tabSize: 2,
|
||||
wordBasedSuggestions: true,
|
||||
}}
|
||||
value={JSON.stringify(row._source, null, 2)}
|
||||
onMount={handleEditorDidMount}
|
||||
/>
|
||||
<div style={{display:'flex', height: '10vh', alignItems:'center', justifyContent:'center'}}>
|
||||
<div style={{marginLeft:'auto'}} >
|
||||
<Button onClick={editCancelClick} style={{marginRight:5}}>Cancel</Button>
|
||||
{/* <Button type="primary" onClick={()=>{}} style={{marginRight:5}}>Save as New</Button> */}
|
||||
<SaveAsNewButton docID={row._id} saveDocumentClick={saveDocumentClick}/>
|
||||
<Button type="primary" onClick={()=>{saveDocumentClick()}} >Save</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Drawer>
|
||||
<div className="euiFlexItem euiFlexItem--flexGrowZero euiText euiText--small">
|
||||
{/* <a
|
||||
className="euiLink"
|
||||
onClick={()=>{setEditorVisble(true)}}
|
||||
>Edit document</a> */}
|
||||
<Dropdown overlay={menu} >
|
||||
<a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
|
||||
Operation <Icon type="down" />
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
{/* <div className="euiFlexItem euiFlexItem--flexGrowZero euiText euiText--small">
|
||||
<a
|
||||
className="euiLink"
|
||||
>View surrounding documents</a>
|
||||
|
@ -45,9 +147,9 @@ export function Detail({
|
|||
<a
|
||||
className="euiLink"
|
||||
>View single document</a>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
<div data-test-subj="docViewer">
|
||||
<DocViewer
|
||||
|
@ -62,5 +164,29 @@ export function Detail({
|
|||
|
||||
</td>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
const SaveAsNewButton = ({docID, saveDocumentClick}:any)=>{
|
||||
const newID = generateNewID(docID);
|
||||
const [newDocID, setNewDocID] = useState(newID)
|
||||
const content = (<div style={{width: 200}}>
|
||||
<div><Input value={newDocID} onChange={(e)=>{
|
||||
setNewDocID(e.target.value)
|
||||
}} /></div>
|
||||
<div style={{marginTop:10}}><Button onClick={()=>{
|
||||
saveDocumentClick(newDocID)
|
||||
}}>确定</Button></div>
|
||||
</div>)
|
||||
return (
|
||||
<Popover
|
||||
content={content}
|
||||
title="Please input new ID"
|
||||
trigger="click"
|
||||
// visible={this.state.visible}
|
||||
// onVisibleChange={this.handleVisibleChange}
|
||||
>
|
||||
<Button style={{marginRight:5}} type="primary">Save as new</Button>
|
||||
</Popover>
|
||||
)
|
||||
}
|
|
@ -13,6 +13,7 @@ interface Props {
|
|||
onAddColumn?: (name: string) => void;
|
||||
onRemoveColumn?: (name: string) => void;
|
||||
row: any;
|
||||
document: any;
|
||||
}
|
||||
|
||||
export function TableRow({
|
||||
|
@ -24,6 +25,7 @@ export function TableRow({
|
|||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
row,
|
||||
document
|
||||
}:Props){
|
||||
const mapping = indexPattern.fields.getByName;
|
||||
const [open,setOpen] = useState(false);
|
||||
|
@ -60,6 +62,7 @@ export function TableRow({
|
|||
<Detail columns={columns}
|
||||
indexPattern={indexPattern}
|
||||
row={row}
|
||||
document={document}
|
||||
onFilter={onFilter}
|
||||
onAddColumn={onAddColumn}
|
||||
onRemoveColumn={onRemoveColumn}/>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
@import '../../../../../core/public/variables.scss';
|
||||
.kbnDocViewerTable {
|
||||
margin-top: $euiSizeS;
|
||||
font-size: 12px;
|
||||
.kbnDocViewer__buttons{
|
||||
padding-top: 0px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.kbnDocViewer {
|
||||
|
|
|
@ -51,8 +51,8 @@ export class DocViewerTab extends React.Component<Props, State> {
|
|||
|
||||
shouldComponentUpdate(nextProps: Props, nextState: State) {
|
||||
return (
|
||||
nextProps.renderProps.hit._id !== this.props.renderProps.hit._id ||
|
||||
nextProps.id !== this.props.id ||
|
||||
nextProps.renderProps.hit !== this.props.renderProps.hit ||
|
||||
nextProps.id !== this.props.id || nextProps.renderProps.columns !== this.props.renderProps.columns ||
|
||||
nextState.hasError
|
||||
);
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ export function DocViewTableRow({
|
|||
<DocViewTableRowBtnCollapse onClick={onToggleCollapse} isCollapsed={isCollapsed} />
|
||||
)}
|
||||
{displayUnderscoreWarning && <DocViewTableRowIconUnderscore />}
|
||||
{displayNoMappingWarning && <DocViewTableRowIconNoMapping />}
|
||||
{/* {displayNoMappingWarning && <DocViewTableRowIconNoMapping />} */}
|
||||
<div
|
||||
className={valueClassName}
|
||||
data-test-subj={`tableDocViewRow-${field}-value`}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
|
||||
|
||||
export interface Props {
|
||||
|
@ -26,9 +25,7 @@ export interface Props {
|
|||
}
|
||||
|
||||
export function DocViewTableRowBtnCollapse({ onClick, isCollapsed }: Props) {
|
||||
const label = i18n.translate('discover.docViews.table.toggleFieldDetails', {
|
||||
defaultMessage: 'Toggle field details',
|
||||
});
|
||||
const label = 'Toggle field details';
|
||||
return (
|
||||
<EuiToolTip content={label}>
|
||||
<EuiButtonIcon
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface Props {
|
||||
onClick: () => void;
|
||||
|
@ -28,23 +26,15 @@ export interface Props {
|
|||
|
||||
export function DocViewTableRowBtnFilterAdd({ onClick, disabled = false }: Props) {
|
||||
const tooltipContent = disabled ? (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.unindexedFieldsCanNotBeSearchedTooltip"
|
||||
defaultMessage="Unindexed fields can not be searched"
|
||||
/>
|
||||
"Unindexed fields can not be searched"
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.filterForValueButtonTooltip"
|
||||
defaultMessage="Filter for value"
|
||||
/>
|
||||
"Filter for value"
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiToolTip content={tooltipContent}>
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate('discover.docViews.table.filterForValueButtonAriaLabel', {
|
||||
defaultMessage: 'Filter for value',
|
||||
})}
|
||||
aria-label='Filter for value'
|
||||
className="kbnDocViewer__actionButton"
|
||||
data-test-subj="addInclusiveFilterButton"
|
||||
disabled={disabled}
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface Props {
|
||||
onClick: () => void;
|
||||
|
@ -34,29 +32,18 @@ export function DocViewTableRowBtnFilterExists({
|
|||
}: Props) {
|
||||
const tooltipContent = disabled ? (
|
||||
scripted ? (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip"
|
||||
defaultMessage="Unable to filter for presence of scripted fields"
|
||||
/>
|
||||
"Unable to filter for presence of scripted fields"
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip"
|
||||
defaultMessage="Unable to filter for presence of meta fields"
|
||||
/>
|
||||
"Unable to filter for presence of meta fields"
|
||||
)
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.filterForFieldPresentButtonTooltip"
|
||||
defaultMessage="Filter for field present"
|
||||
/>
|
||||
"Filter for field present"
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiToolTip content={tooltipContent}>
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate('discover.docViews.table.filterForFieldPresentButtonAriaLabel', {
|
||||
defaultMessage: 'Filter for field present',
|
||||
})}
|
||||
aria-label='Filter for field present'
|
||||
onClick={onClick}
|
||||
className="kbnDocViewer__actionButton"
|
||||
data-test-subj="addExistsFilterButton"
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface Props {
|
||||
onClick: () => void;
|
||||
|
@ -28,23 +26,15 @@ export interface Props {
|
|||
|
||||
export function DocViewTableRowBtnFilterRemove({ onClick, disabled = false }: Props) {
|
||||
const tooltipContent = disabled ? (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.unindexedFieldsCanNotBeSearchedTooltip"
|
||||
defaultMessage="Unindexed fields can not be searched"
|
||||
/>
|
||||
"Unindexed fields can not be searched"
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.filterOutValueButtonTooltip"
|
||||
defaultMessage="Filter out value"
|
||||
/>
|
||||
"Filter out value"
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiToolTip content={tooltipContent}>
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate('discover.docViews.table.filterOutValueButtonAriaLabel', {
|
||||
defaultMessage: 'Filter out value',
|
||||
})}
|
||||
aria-label= 'Filter out value'
|
||||
className="kbnDocViewer__actionButton"
|
||||
data-test-subj="removeInclusiveFilterButton"
|
||||
disabled={disabled}
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface Props {
|
||||
active: boolean;
|
||||
|
@ -31,9 +29,7 @@ export function DocViewTableRowBtnToggleColumn({ onClick, active, disabled = fal
|
|||
if (disabled) {
|
||||
return (
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate('discover.docViews.table.toggleColumnInTableButtonAriaLabel', {
|
||||
defaultMessage: 'Toggle column in table',
|
||||
})}
|
||||
aria-label= 'Toggle column in table'
|
||||
className="kbnDocViewer__actionButton"
|
||||
data-test-subj="toggleColumnButton"
|
||||
disabled
|
||||
|
@ -44,17 +40,10 @@ export function DocViewTableRowBtnToggleColumn({ onClick, active, disabled = fal
|
|||
}
|
||||
return (
|
||||
<EuiToolTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
id="discover.docViews.table.toggleColumnInTableButtonTooltip"
|
||||
defaultMessage="Toggle column in table"
|
||||
/>
|
||||
}
|
||||
content="Toggle column in table"
|
||||
>
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate('discover.docViews.table.toggleColumnInTableButtonAriaLabel', {
|
||||
defaultMessage: 'Toggle column in table',
|
||||
})}
|
||||
aria-label= 'Toggle column in table'
|
||||
aria-pressed={active}
|
||||
onClick={onClick}
|
||||
className="kbnDocViewer__actionButton"
|
||||
|
|
|
@ -18,19 +18,11 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { EuiIconTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function DocViewTableRowIconNoMapping() {
|
||||
const ariaLabel = i18n.translate('discover.docViews.table.noCachedMappingForThisFieldAriaLabel', {
|
||||
defaultMessage: 'Warning',
|
||||
});
|
||||
const tooltipContent = i18n.translate(
|
||||
'discover.docViews.table.noCachedMappingForThisFieldTooltip',
|
||||
{
|
||||
defaultMessage:
|
||||
'No cached mapping for this field. Refresh field list from the Management > Index Patterns page',
|
||||
}
|
||||
);
|
||||
const ariaLabel = 'Warning';
|
||||
const tooltipContent =
|
||||
'No cached mapping for this field. Refresh field list from the Management > Index Patterns page';
|
||||
return (
|
||||
<EuiIconTip
|
||||
aria-label={ariaLabel}
|
||||
|
|
|
@ -18,22 +18,10 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { EuiIconTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function DocViewTableRowIconUnderscore() {
|
||||
const ariaLabel = i18n.translate(
|
||||
'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Warning',
|
||||
}
|
||||
);
|
||||
const tooltipContent = i18n.translate(
|
||||
'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedTooltip',
|
||||
{
|
||||
defaultMessage: 'Field names beginning with {underscoreSign} are not supported',
|
||||
values: { underscoreSign: '_' },
|
||||
}
|
||||
);
|
||||
const ariaLabel = 'Warning';
|
||||
const tooltipContent = 'Field names beginning with _ are not supported';
|
||||
|
||||
return (
|
||||
<EuiIconTip
|
||||
|
|
|
@ -26,6 +26,7 @@ import { createGetterSetter } from '../../kibana_utils/common/';
|
|||
import { search } from '../../data/public';
|
||||
import { DocViewsRegistry } from './application/doc_views/doc_views_registry';
|
||||
import { JsonCodeBlock } from './application/components/json_code_block/json_code_block';
|
||||
import { DocViewTable } from './application/components/table/table';
|
||||
|
||||
let angularModule: any = null;
|
||||
let services: DiscoverServices | null = null;
|
||||
|
@ -74,11 +75,11 @@ export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter<Doc
|
|||
|
||||
const docViewsRegistry = new DocViewsRegistry();
|
||||
setDocViewsRegistry(docViewsRegistry);
|
||||
// docViewsRegistry.addDocView({
|
||||
// title: 'Table',
|
||||
// order: 10,
|
||||
// component: DocViewTable,
|
||||
// });
|
||||
docViewsRegistry.addDocView({
|
||||
title: 'Table',
|
||||
order: 10,
|
||||
component: DocViewTable,
|
||||
});
|
||||
docViewsRegistry.addDocView({
|
||||
title: 'JSON',
|
||||
order: 20,
|
||||
|
|
|
@ -46,6 +46,7 @@ import clusterBg from '@/assets/cluster_bg.png';
|
|||
|
||||
export interface EditIndexPatternProps extends RouteComponentProps {
|
||||
indexPattern: IndexPattern;
|
||||
id: string;
|
||||
}
|
||||
|
||||
const mappingAPILink = 'Mapping API';
|
||||
|
@ -65,7 +66,7 @@ const confirmModalOptionsDelete = {
|
|||
};
|
||||
|
||||
export const EditIndexPattern = withRouter(
|
||||
({ indexPattern, history, location }: EditIndexPatternProps) => {
|
||||
({ indexPattern, history, location, id }: EditIndexPatternProps) => {
|
||||
const {
|
||||
uiSettings,
|
||||
indexPatternManagementStart,
|
||||
|
@ -131,8 +132,8 @@ export const EditIndexPattern = withRouter(
|
|||
uiSettings.set('defaultIndex', otherPatterns[0].id);
|
||||
}
|
||||
}
|
||||
if (indexPattern.id) {
|
||||
Promise.resolve(data.indexPatterns.delete(indexPattern.id)).then(function () {
|
||||
if (indexPattern.id || id) {
|
||||
Promise.resolve(data.indexPatterns.delete(indexPattern.id || id)).then(function () {
|
||||
history.push('');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ const EditIndexPatternCont: React.FC<RouteComponentProps<{ id: string }>> = ({ .
|
|||
}, [data.indexPatterns, props.match.params.id, ]); //setBreadcrumbs
|
||||
|
||||
if (indexPattern) {
|
||||
return <EditIndexPattern indexPattern={indexPattern} />;
|
||||
return <EditIndexPattern indexPattern={indexPattern} id={indexPattern.id} />;
|
||||
} else {
|
||||
return <></>;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import React from 'react';
|
||||
import { EuiFlexGroup, EuiToolTip, EuiFlexItem, EuiTitle, EuiButtonIcon } from '@elastic/eui';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import {Popconfirm} from 'antd';
|
||||
|
||||
interface IndexHeaderProps {
|
||||
indexPattern: IIndexPattern;
|
||||
|
@ -88,13 +89,15 @@ export function IndexHeader({
|
|||
{deleteIndexPatternClick && (
|
||||
<EuiFlexItem>
|
||||
<EuiToolTip content={removeTooltip}>
|
||||
<EuiButtonIcon
|
||||
color="danger"
|
||||
onClick={deleteIndexPatternClick}
|
||||
iconType="trash"
|
||||
aria-label={removeAriaLabel}
|
||||
data-test-subj="deleteIndexPatternButton"
|
||||
/>
|
||||
<Popconfirm title="确定要删除?" onConfirm={deleteIndexPatternClick}>
|
||||
<EuiButtonIcon
|
||||
color="danger"
|
||||
// onClick={deleteIndexPatternClick}
|
||||
iconType="trash"
|
||||
aria-label={removeAriaLabel}
|
||||
data-test-subj="deleteIndexPatternButton"
|
||||
/>
|
||||
</Popconfirm>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import {List} from 'antd';
|
||||
import {List, ConfigProvider, Button} from 'antd';
|
||||
import {AlertItem, AlertRecord} from './AlertItem';
|
||||
import './alertlist.scss';
|
||||
import {Legend, LegendItem} from './Legend';
|
||||
import {router} from 'umi';
|
||||
|
||||
|
||||
interface AlertListProps {
|
||||
dataSource: AlertRecord[];
|
||||
|
@ -9,6 +11,7 @@ interface AlertListProps {
|
|||
title: string;
|
||||
onItemClick: (item: AlertRecord)=>void;
|
||||
legendItems?: LegendItem[];
|
||||
onEmptyClick?: ()=>void;
|
||||
}
|
||||
|
||||
export const AlertList = ({
|
||||
|
@ -16,38 +19,54 @@ export const AlertList = ({
|
|||
pagination,
|
||||
title,
|
||||
onItemClick,
|
||||
legendItems
|
||||
legendItems,
|
||||
onEmptyClick,
|
||||
}: AlertListProps)=>{
|
||||
if(typeof onEmptyClick !== 'function'){
|
||||
onEmptyClick = ()=>{
|
||||
router.push('/alerting/monitor/create-monitor');
|
||||
}
|
||||
}
|
||||
|
||||
const AlertRenderEmpty = ()=>{
|
||||
return <div>
|
||||
<Button type="primary" onClick={onEmptyClick}>创建监控项</Button>
|
||||
</div>
|
||||
}
|
||||
return (
|
||||
<div className="alert-list">
|
||||
<div className="header">
|
||||
<div className="title">
|
||||
{title}
|
||||
<span className="total">({pagination?.total})</span>
|
||||
</div>
|
||||
{
|
||||
legendItems ? ( <div className="legend">
|
||||
<Legend items={legendItems}/>
|
||||
</div>):null
|
||||
}
|
||||
|
||||
</div>
|
||||
<List
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
pagination={{
|
||||
onChange: page => {
|
||||
console.log(page);
|
||||
},
|
||||
pageSize: 20,
|
||||
...pagination,
|
||||
}}
|
||||
dataSource={dataSource}
|
||||
renderItem={item => (
|
||||
<AlertItem item={item} onClick={onItemClick} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="alert-list-layout">
|
||||
<div className="title">
|
||||
{title}
|
||||
<span className="total">({pagination?.total})</span>
|
||||
</div>
|
||||
<div className="alert-list">
|
||||
<div className="header">
|
||||
{
|
||||
legendItems ? ( <div className="legend">
|
||||
<Legend items={legendItems}/>
|
||||
</div>):null
|
||||
}
|
||||
|
||||
</div>
|
||||
<ConfigProvider renderEmpty={AlertRenderEmpty}>
|
||||
<List
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
pagination={{
|
||||
onChange: page => {
|
||||
console.log(page);
|
||||
},
|
||||
pageSize: 20,
|
||||
...pagination,
|
||||
}}
|
||||
dataSource={dataSource}
|
||||
renderItem={item => (
|
||||
<AlertItem item={item} onClick={onItemClick} />
|
||||
)}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
|
|
@ -3,19 +3,22 @@
|
|||
padding: 10px 5px;
|
||||
.header{
|
||||
display: flex;
|
||||
.title{
|
||||
color: #333;
|
||||
font-weight:600;
|
||||
padding-bottom: 6px;
|
||||
.total{
|
||||
color: #999;
|
||||
margin-left: 15px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.legend{
|
||||
margin-left: auto;
|
||||
}
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
.alert-list-layout{
|
||||
.title{
|
||||
color: #333;
|
||||
font-weight:600;
|
||||
font-size: 16px;
|
||||
padding-bottom: 6px;
|
||||
.total{
|
||||
color: #999;
|
||||
margin-left: 15px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -76,22 +76,26 @@ export const AlertOverview = (props: any)=>{
|
|||
return (
|
||||
<div className="alert-overview">
|
||||
<div className="left">
|
||||
<AlertList dataSource={alerts.data as any}
|
||||
title={formatMessage({id:'alert.overview.alertlist.title'})}
|
||||
onItemClick={onItemClick}
|
||||
pagination={{
|
||||
pageSize,
|
||||
total: alerts.total,
|
||||
onChange: onAlertPageChange,
|
||||
}}/>
|
||||
<div>
|
||||
<AlertList dataSource={alerts.data}
|
||||
title={formatMessage({id:'alert.overview.alertlist.title'})}
|
||||
onItemClick={onItemClick}
|
||||
pagination={{
|
||||
pageSize,
|
||||
total: alerts.total,
|
||||
onChange: onAlertPageChange,
|
||||
}}/>
|
||||
</div>
|
||||
<div style={{marginTop:10}}>
|
||||
<AlertList dataSource={historyAlerts.data}
|
||||
title={formatMessage({id:'alert.overview.alertlist-history.title'})}
|
||||
onItemClick={onItemClick}
|
||||
pagination={{
|
||||
pageSize,
|
||||
total: historyAlerts.total,
|
||||
onChange: onAlertHistoryPageChange,
|
||||
}}/>
|
||||
title={formatMessage({id:'alert.overview.alertlist-history.title'})}
|
||||
onItemClick={onItemClick}
|
||||
pagination={{
|
||||
pageSize,
|
||||
total: historyAlerts.total,
|
||||
onChange: onAlertHistoryPageChange,
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="right">
|
||||
<div>提示</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, {useEffect, useState, useMemo} from "react";
|
||||
import {Spin, Card} from 'antd';
|
||||
import {Spin, Card, Empty, Button} from 'antd';
|
||||
import {Fetch} from '../../../../components/kibana/core/public/http/fetch';
|
||||
import './overview.scss';
|
||||
import {
|
||||
|
@ -148,7 +148,49 @@ export default (props)=>{
|
|||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
<div>
|
||||
<div className="charts">
|
||||
<div style={{height:'150px'}} className="chart">
|
||||
<Chart>
|
||||
<Settings theme={theme} />
|
||||
<Axis id="bottom" position={Position.Bottom} title="Last 3 months" showOverlappingTicks tickFormat={timeFormatter(niceTimeFormatByDay(data.metrics.last_tree_month.day))} />
|
||||
<Axis
|
||||
id="left"
|
||||
title="Alert number"
|
||||
position={Position.Left}
|
||||
/>
|
||||
<LineSeries
|
||||
id="lines"
|
||||
xScaleType={ScaleType.Time}
|
||||
yScaleType={ScaleType.Linear}
|
||||
xAccessor={0}
|
||||
yAccessors={[1]}
|
||||
data={data.metrics.last_tree_month?.data || []}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
<div style={{height:'150px', marginTop: 10}} className="chart">
|
||||
<Chart>
|
||||
<Settings showLegend showLegendExtra legendPosition={Position.Right} theme={theme} />
|
||||
<Axis id="bottom" position={Position.Bottom} title="Top 10 cluster" showOverlappingTicks />
|
||||
<Axis id="left2" title="Alert number" position={Position.Left} tickFormat={(d) => Number(d).toFixed(0)} />
|
||||
|
||||
<BarSeries
|
||||
id="bars"
|
||||
xScaleType={ScaleType.Linear}
|
||||
yScaleType={ScaleType.Linear}
|
||||
xAccessor="x"
|
||||
yAccessors={['y']}
|
||||
stackAccessors={['x']}
|
||||
splitSeriesAccessors={['g']}
|
||||
data={data.metrics.top_ten_cluster?.data || []}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
</div>
|
||||
<div className="alertlist-item">
|
||||
{alerts.data.length == 0 && historyAlerts.data.length == 0 && <Empty description=''>
|
||||
<Button>创建监控项</Button>
|
||||
</Empty>}
|
||||
<AlertList dataSource={alerts.data}
|
||||
title={formatMessage({id:'alert.overview.alertlist.title'})}
|
||||
legendItems={pickLegendItems(['ACTIVE','ERROR','ACKNOWLEDGED'])}
|
||||
|
@ -159,7 +201,7 @@ export default (props)=>{
|
|||
onChange: onAlertPageChange,
|
||||
}}/>
|
||||
</div>
|
||||
<div style={{marginTop:10}}>
|
||||
{historyAlerts.data.length > 0 && <div className="alertlist-item">
|
||||
<AlertList dataSource={historyAlerts.data}
|
||||
title={formatMessage({id:'alert.overview.alertlist-history.title'})}
|
||||
onItemClick={onItemClick}
|
||||
|
@ -169,47 +211,11 @@ export default (props)=>{
|
|||
total: historyAlerts.total,
|
||||
onChange: onAlertHistoryPageChange,
|
||||
}}/>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
<div className="right">
|
||||
<div style={{height:'150px'}}>
|
||||
<Chart>
|
||||
<Settings theme={theme} />
|
||||
<Axis id="bottom" position={Position.Bottom} title="Last 3 months" showOverlappingTicks tickFormat={timeFormatter(niceTimeFormatByDay(data.metrics.last_tree_month.day))} />
|
||||
<Axis
|
||||
id="left"
|
||||
title="Alert number"
|
||||
position={Position.Left}
|
||||
/>
|
||||
<LineSeries
|
||||
id="lines"
|
||||
xScaleType={ScaleType.Time}
|
||||
yScaleType={ScaleType.Linear}
|
||||
xAccessor={0}
|
||||
yAccessors={[1]}
|
||||
data={data.metrics.last_tree_month?.data || []}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
<div style={{height:'150px', marginTop: 10}}>
|
||||
<Chart>
|
||||
<Settings showLegend showLegendExtra legendPosition={Position.Right} theme={theme} />
|
||||
<Axis id="bottom" position={Position.Bottom} title="Top 10 cluster" showOverlappingTicks />
|
||||
<Axis id="left2" title="Alert number" position={Position.Left} tickFormat={(d) => Number(d).toFixed(0)} />
|
||||
|
||||
<BarSeries
|
||||
id="bars"
|
||||
xScaleType={ScaleType.Linear}
|
||||
yScaleType={ScaleType.Linear}
|
||||
xAccessor="x"
|
||||
yAccessors={['y']}
|
||||
stackAccessors={['x']}
|
||||
splitSeriesAccessors={['g']}
|
||||
data={data.metrics.top_ten_cluster?.data || []}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
.layout{
|
||||
display: flex;
|
||||
// display: flex;
|
||||
.left{
|
||||
display: flex;
|
||||
flex: 1 1 60%;
|
||||
flex-direction: column;
|
||||
// display: flex;
|
||||
// flex: 1 1 60%;
|
||||
// flex-direction: column;
|
||||
.state-count{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -21,9 +21,19 @@
|
|||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.alertlist-item{
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
.charts{
|
||||
display: flex;
|
||||
margin-top: 25px;
|
||||
>.chart{
|
||||
flex: 1 1 50%;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
flex: 1 1 40%;
|
||||
|
@ -31,6 +41,6 @@
|
|||
}
|
||||
|
||||
.overview-wrapper {
|
||||
padding: 10px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
}
|
|
@ -227,7 +227,7 @@ class Overview extends React.Component {
|
|||
>
|
||||
<Card.Meta title='存储空间' className={styles.title} />
|
||||
<div>
|
||||
<span className={styles.total}>{totalStoreSize.size}</span><span className={styles.unit}>{totalStoreSize.unit}</span>
|
||||
<span className={styles.total}>{totalStoreSize.size || '-'}</span><span className={styles.unit}>{totalStoreSize.unit}</span>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
|
|
|
@ -31,7 +31,7 @@ import * as styles from './discover.scss';
|
|||
import { Subscription } from 'rxjs';
|
||||
import { connect } from 'dva';
|
||||
|
||||
import { Card, Spin } from 'antd';
|
||||
import { Card, Spin, message } from 'antd';
|
||||
// import DiscoverGrid from './Components/discover_grid';
|
||||
import {flattenHitWrapper} from '../../components/kibana/data/common/index_patterns/index_patterns';
|
||||
import {getStateColumnActions} from '../../components/kibana/discover/public/application/angular/doc_table/actions/columns';
|
||||
|
@ -56,8 +56,6 @@ const SidebarMemoized = React.memo(DiscoverSidebar);
|
|||
const {filterManager, queryStringManager, timefilter, storage, getEsQuery, getSearchParams,
|
||||
intervalOptions, getTimeBuckets, fetchESRequest, services} = getContext();
|
||||
|
||||
//const histogramData = buildPointSeriesData(chartTable, dimensions);
|
||||
|
||||
const SearchBar = createSearchBar();
|
||||
|
||||
|
||||
|
@ -246,7 +244,7 @@ const Discover = (props)=>{
|
|||
state,
|
||||
useNewFieldsApi:false,
|
||||
}),
|
||||
[indexPattern, state]
|
||||
[indexPattern,state]
|
||||
);
|
||||
|
||||
const collapseIcon = useRef(null);
|
||||
|
@ -309,6 +307,41 @@ const Discover = (props)=>{
|
|||
const hits = searchRes.hits.total?.value || searchRes.hits.total;
|
||||
const resetQuery = ()=>{};
|
||||
const showDatePicker = indexPattern.timeFieldName != "";
|
||||
|
||||
const saveDocument = useCallback(async ({_index, _id, _type, _source})=>{
|
||||
const {http} = getContext();
|
||||
const res = await http.put(`/elasticsearch/${props.selectedCluster.id}/doc/${_index}/${_id}`, {
|
||||
prependBasePath: false,
|
||||
query: {
|
||||
_type,
|
||||
},
|
||||
body: JSON.stringify(_source),
|
||||
});
|
||||
if(res.error){
|
||||
message.error(res.error)
|
||||
return res
|
||||
}
|
||||
message.success('saved successfully');
|
||||
updateQuery()
|
||||
return res
|
||||
},[props.selectedCluster])
|
||||
|
||||
const deleteDocument = useCallback(async ({_index, _id, _type})=>{
|
||||
const {http} = getContext();
|
||||
const res = await http.delete(`/elasticsearch/${props.selectedCluster.id}/doc/${_index}/${_id}`, {
|
||||
prependBasePath: false,
|
||||
query: {
|
||||
_type,
|
||||
}
|
||||
});
|
||||
if(res.error){
|
||||
message.error(res.error)
|
||||
return res
|
||||
}
|
||||
message.success('deleted successfully');
|
||||
updateQuery()
|
||||
return res
|
||||
},[props.selectedCluster])
|
||||
|
||||
return (
|
||||
<Card bordered={false}>
|
||||
|
@ -495,7 +528,9 @@ const Discover = (props)=>{
|
|||
onFilter={onAddFilter}
|
||||
onRemoveColumn={onRemoveColumn}
|
||||
onMoveColumn={onMoveColumn}
|
||||
onAddColumn={onAddColumn}
|
||||
onChangeSortOrder={onSort}
|
||||
document={{saveDocument, deleteDocument}}
|
||||
hits={rows}/>
|
||||
</div>
|
||||
):null}
|
||||
|
|
|
@ -383,14 +383,10 @@ class EditableCell extends React.Component {
|
|||
|
||||
getFieldType = (record, key)=>{
|
||||
const {doclist} = this.props;
|
||||
// if(!doclist.mappings[record._index]){
|
||||
// console.log(record, doclist.mappings)
|
||||
// return
|
||||
// }
|
||||
let properties = null;
|
||||
let _type = record._type || doclist._type;
|
||||
if(typeof _type !== 'undefined' && _type !== '' && _type !== '_doc'){
|
||||
properties = doclist.mappings[record._index].mappings[_type].properties;
|
||||
properties = doclist.mappings[record._index].mappings[_type]?.properties || {};
|
||||
}else{
|
||||
properties = doclist.mappings[record._index].mappings.properties;
|
||||
}
|
||||
|
@ -565,9 +561,10 @@ class EditableCell extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
@connect(({document,cluster})=>({
|
||||
@connect(({document,global})=>({
|
||||
document,
|
||||
cluster,
|
||||
clusterID: global.selectedClusterID,
|
||||
cluster: global.selectedCluster,
|
||||
}))
|
||||
@Form.create()
|
||||
class Doucment extends React.Component {
|
||||
|
@ -580,10 +577,13 @@ class Doucment extends React.Component {
|
|||
// }
|
||||
|
||||
fetchData = (params) => {
|
||||
const {dispatch} = this.props;
|
||||
const {dispatch, clusterID} = this.props;
|
||||
return dispatch({
|
||||
type: 'document/fetchDocList',
|
||||
payload: params,
|
||||
payload: {
|
||||
...params,
|
||||
clusterID
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -595,38 +595,28 @@ class Doucment extends React.Component {
|
|||
langDisposer.dispose();
|
||||
}
|
||||
}
|
||||
componentDidMount(){
|
||||
// initEditor()
|
||||
const {location, dispatch } = this.props;
|
||||
//console.log(match, location);
|
||||
let index = location.query.index;
|
||||
let cluster = location.query.cluster || 'single-es';
|
||||
if(!cluster){
|
||||
return
|
||||
componentDidUpdate(oldProps,newState,snapshot){
|
||||
if(oldProps.clusterID != this.props.clusterID){
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
initData = ()=>{
|
||||
const {dispatch, clusterID} = this.props;
|
||||
dispatch({
|
||||
type: 'document/fetchMappings',
|
||||
payload: {
|
||||
cluster,
|
||||
clusterID,
|
||||
}
|
||||
});
|
||||
dispatch({
|
||||
type: 'document/fetchIndices',
|
||||
payload: {
|
||||
cluster,
|
||||
clusterID,
|
||||
}
|
||||
}).then(()=>{
|
||||
if(!index){
|
||||
return
|
||||
}
|
||||
this.fetchData({
|
||||
pageSize: 10,
|
||||
pageIndex: 1,
|
||||
cluster,
|
||||
index,
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
componentDidMount(){
|
||||
this.initData()
|
||||
}
|
||||
|
||||
handleNewClick = ()=>{
|
||||
|
@ -644,7 +634,6 @@ class Doucment extends React.Component {
|
|||
let _index = indices[0];
|
||||
let _type = '';
|
||||
if(indices.length > 0){
|
||||
//console.log(this.indexSelEl);
|
||||
let vals = this.indexSelEl.state.value;
|
||||
if(vals.length === 0){
|
||||
Modal.error({
|
||||
|
@ -701,9 +690,8 @@ class Doucment extends React.Component {
|
|||
handleSearchClick = (e)=>{
|
||||
let value = this.keywordEl.state.value;
|
||||
let index = this.indexEl.state.value;
|
||||
let cluster = this.clusterEl.rcSelect.state.value[0];
|
||||
let filter = '';
|
||||
if(!cluster || !index){
|
||||
if(!index){
|
||||
message.error('please select cluster and index');
|
||||
return;
|
||||
}
|
||||
|
@ -711,7 +699,6 @@ class Doucment extends React.Component {
|
|||
filter = this.filterGetter();
|
||||
}
|
||||
this.fetchData({
|
||||
cluster,
|
||||
index,
|
||||
pageSize: this.props.document.pageSize,
|
||||
pageIndex: 1,
|
||||
|
@ -719,10 +706,10 @@ class Doucment extends React.Component {
|
|||
filter,
|
||||
keyword: value,
|
||||
}).then(()=>{
|
||||
if(this.hashChanged){
|
||||
router.push(`/data/document?cluster=${cluster}&index=${index}`);
|
||||
this.hashChanged = !this.hashChanged;
|
||||
}
|
||||
// if(this.hashChanged){
|
||||
// router.push(`/data/document?cluster=${cluster}&index=${index}`);
|
||||
// this.hashChanged = !this.hashChanged;
|
||||
// }
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -741,8 +728,9 @@ class Doucment extends React.Component {
|
|||
// if((indices && indices.length > 1)){
|
||||
// return;
|
||||
// }
|
||||
const {major} = this.props.cluster;
|
||||
if(indices && indices.length >= 0){
|
||||
const {version} = this.props.cluster;
|
||||
const major = version.split('.')?.[0] || '';
|
||||
if(indices && indices.length >= 0 && major !=''){
|
||||
indices = getESAPI(major).extractIndicesFromMappings(mappings).filter(item=>{
|
||||
if(indices.length > 0){
|
||||
return indices.indexOf(item.index) > -1;
|
||||
|
@ -769,11 +757,6 @@ class Doucment extends React.Component {
|
|||
<div>
|
||||
{(indices && indices.length>0) ? (<Cascader ref={el=>{this.indexSelEl=el}} onChange={(vals)=>{this.handleResultTabKeyChange(vals[0])}} value={[resultKey]} options={indices} style={{width: 200, marginRight:5}} placeholder="please select a index">
|
||||
</Cascader>) : ''}
|
||||
{/*{(indices) ? (<Select ref={el=>{this.indexSelEl=el}} style={{width: 200, marginRight:5}} placeholder="please select a index">*/}
|
||||
{/* {indices.map(item=>{*/}
|
||||
{/* return (<Select.Option key={item} label={item}>{item}</Select.Option>)*/}
|
||||
{/* })}*/}
|
||||
{/*</Select>) : ''}*/}
|
||||
<Button type="primary" icon="plus" onClick={this.handleNewClick}>{formatMessage({ id: 'form.button.new' })}</Button>
|
||||
<span style={{marginLeft:20}}>
|
||||
{/*Select Viewer: */}
|
||||
|
@ -806,9 +789,7 @@ class Doucment extends React.Component {
|
|||
value: index,
|
||||
};
|
||||
})
|
||||
const clusters = ["single-es"];
|
||||
let {cluster, index, indices, tableMode}= this.props.document;
|
||||
cluster = cluster || this.props.location.query.cluster || 'single-es';
|
||||
let {index, indices, tableMode}= this.props.document;
|
||||
index = index || this.props.location.query.index;
|
||||
indices = indices || [];
|
||||
|
||||
|
@ -824,12 +805,7 @@ class Doucment extends React.Component {
|
|||
<Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
|
||||
<Col span={20} style={{paddingLeft:0}}>
|
||||
<Input.Group compact>
|
||||
<Select ref={el=>this.clusterEl=el} defaultValue={cluster} style={{width: '20%'}}>
|
||||
{
|
||||
clusters.map(op=>(<Select.Option value={op} key={op}>{op}</Select.Option>))
|
||||
}
|
||||
</Select>
|
||||
<InputSelect data={clusterIndices} onChange={()=>{this.hashChanged=true;}} defaultValue={index} ref={el=>{this.indexEl=el}} placeholder="input index or index pattern" style={{width: '25%'}}/>
|
||||
<InputSelect data={clusterIndices} onChange={()=>{this.hashChanged=true;}} defaultValue={index} ref={el=>{this.indexEl=el}} placeholder="input index or index pattern" style={{width: '40%'}}/>
|
||||
<Input
|
||||
style={{width:"40%", display: this.state.bodyDisplay === 'none' ? 'inline': 'none'}}
|
||||
ref={el=>this.keywordEl=el}
|
||||
|
|
|
@ -17,12 +17,14 @@ import {
|
|||
Menu,
|
||||
Table,
|
||||
Dropdown,
|
||||
Icon, Popconfirm
|
||||
Icon, Popconfirm,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
import Editor from '@monaco-editor/react';
|
||||
|
||||
import styles from '../List/TableList.less';
|
||||
import {transformSettingsForApi} from '@/lib/elasticsearch/edit_settings';
|
||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { TextArea } = Input;
|
||||
|
@ -107,8 +109,9 @@ class CreateForm extends React.Component {
|
|||
|
||||
|
||||
/* eslint react/no-multi-comp:0 */
|
||||
@connect(({ index }) => ({
|
||||
index
|
||||
@connect(({ index,global }) => ({
|
||||
index,
|
||||
clusterID: global.selectedClusterID,
|
||||
}))
|
||||
@Form.create()
|
||||
class Index extends PureComponent {
|
||||
|
@ -120,6 +123,7 @@ class Index extends PureComponent {
|
|||
drawerVisible: false,
|
||||
editingIndex:{},
|
||||
indexActiveKey: '1',
|
||||
showSystemIndices: false,
|
||||
};
|
||||
columns = [
|
||||
{
|
||||
|
@ -137,6 +141,9 @@ class Index extends PureComponent {
|
|||
{
|
||||
title: '文档数',
|
||||
dataIndex: 'docs_count',
|
||||
render: (val)=>{
|
||||
return val || 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '主分片数',
|
||||
|
@ -165,13 +172,18 @@ class Index extends PureComponent {
|
|||
componentDidMount() {
|
||||
this.fetchData()
|
||||
}
|
||||
componentDidUpdate(oldProps,newState,snapshot){
|
||||
if(oldProps.clusterID != this.props.clusterID){
|
||||
this.fetchData()
|
||||
}
|
||||
}
|
||||
|
||||
fetchData = ()=>{
|
||||
const { dispatch } = this.props;
|
||||
const { dispatch, clusterID } = this.props;
|
||||
dispatch({
|
||||
type: 'index/fetchIndices',
|
||||
payload: {
|
||||
cluster: 'single-es'
|
||||
clusterID: clusterID,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -185,11 +197,12 @@ class Index extends PureComponent {
|
|||
};
|
||||
|
||||
handleDeleteClick = (indexName) => {
|
||||
const { dispatch } = this.props;
|
||||
const { dispatch,clusterID } = this.props;
|
||||
dispatch({
|
||||
type: 'index/removeIndex',
|
||||
payload: {
|
||||
index: indexName
|
||||
index: indexName,
|
||||
clusterID,
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -214,12 +227,13 @@ class Index extends PureComponent {
|
|||
};
|
||||
|
||||
handleAdd = fields => {
|
||||
const { dispatch } = this.props;
|
||||
const { dispatch, clusterID} = this.props;
|
||||
dispatch({
|
||||
type: 'index/addIndex',
|
||||
payload: {
|
||||
index: fields.index,
|
||||
config: JSON.parse(fields.config)
|
||||
config: JSON.parse(fields.config || '{}'),
|
||||
clusterID
|
||||
},
|
||||
});
|
||||
this.handleModalVisible();
|
||||
|
@ -229,7 +243,7 @@ class Index extends PureComponent {
|
|||
this.setState({
|
||||
indexActiveKey: activeKey,
|
||||
})
|
||||
const {dispatch} = this.props;
|
||||
const {dispatch, clusterID} = this.props;
|
||||
if(activeKey == '2'){
|
||||
if(this.props.index.mappings[indexName]){
|
||||
return
|
||||
|
@ -238,6 +252,7 @@ class Index extends PureComponent {
|
|||
type: 'index/fetchMappings',
|
||||
payload: {
|
||||
index: indexName,
|
||||
clusterID,
|
||||
}
|
||||
})
|
||||
}else if(activeKey == '4'){
|
||||
|
@ -248,6 +263,7 @@ class Index extends PureComponent {
|
|||
type: 'index/fetchSettings',
|
||||
payload: {
|
||||
index: indexName,
|
||||
clusterID,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -259,12 +275,13 @@ class Index extends PureComponent {
|
|||
handleIndexSettingsSaveClick = (indexName)=>{
|
||||
let settings = this.indexSettingsGetter();
|
||||
settings = JSON.parse(settings);
|
||||
const {dispatch} = this.props;
|
||||
const {dispatch,clusterID} = this.props;
|
||||
dispatch({
|
||||
type: 'index/saveSettings',
|
||||
payload: {
|
||||
index: indexName,
|
||||
settings: settings,
|
||||
clusterID,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -281,6 +298,9 @@ class Index extends PureComponent {
|
|||
}
|
||||
indices.push(clusterIndices[key]);
|
||||
}
|
||||
if(!this.state.showSystemIndices){
|
||||
indices = indices.filter(item=>!item.index.startsWith('.'));
|
||||
}
|
||||
const { modalVisible, updateModalVisible, updateFormValues,editingIndex, drawerVisible } = this.state;
|
||||
const parentMethods = {
|
||||
handleAdd: this.handleAdd,
|
||||
|
@ -301,7 +321,7 @@ class Index extends PureComponent {
|
|||
const {form: { getFieldDecorator }} = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageHeaderWrapper>
|
||||
<Card bordered={false}>
|
||||
<div className={styles.tableList}>
|
||||
<div className={styles.tableListForm}>
|
||||
|
@ -332,7 +352,9 @@ class Index extends PureComponent {
|
|||
</Form>
|
||||
</div>
|
||||
<div className={styles.tableListOperator}>
|
||||
|
||||
<div style={{marginLeft:'auto'}}>显示系统索引<Switch style={{marginLeft:5}}
|
||||
onChange={(checked)=>{this.setState({showSystemIndices:checked})}}
|
||||
defaultChecked={this.state.showSystemIndices}/></div>
|
||||
</div>
|
||||
<Table bordered
|
||||
dataSource={indices}
|
||||
|
@ -357,17 +379,17 @@ class Index extends PureComponent {
|
|||
>
|
||||
<Tabs activeKey={this.state.indexActiveKey} onChange={(activeKey)=>{this.handleIndexTabChanged(activeKey, editingIndex.index)}}>
|
||||
<TabPane tab="概览" key="1">
|
||||
<Descriptions title="General" column={2}>
|
||||
<Descriptions column={2}>
|
||||
<Descriptions.Item label="健康">{editingIndex.health}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">{editingIndex.status}</Descriptions.Item>
|
||||
<Descriptions.Item label="主分片数">{editingIndex.shards}</Descriptions.Item>
|
||||
<Descriptions.Item label="副分片数">{editingIndex.replicas}</Descriptions.Item>
|
||||
<Descriptions.Item label="文档数">{editingIndex.docs_count}</Descriptions.Item>
|
||||
<Descriptions.Item label="删除文档数">{editingIndex.docs_deleted}</Descriptions.Item>
|
||||
<Descriptions.Item label="存贮大小"></Descriptions.Item>
|
||||
<Descriptions.Item label="主存贮大小"></Descriptions.Item>
|
||||
<Descriptions.Item label="别名">
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="存贮大小">{editingIndex.store_size}</Descriptions.Item>
|
||||
<Descriptions.Item label="主存贮大小">{editingIndex.pri_store_size}</Descriptions.Item>
|
||||
{/* <Descriptions.Item label="别名">
|
||||
</Descriptions.Item> */}
|
||||
</Descriptions>
|
||||
</TabPane>
|
||||
<TabPane tab="Mappings" key="2">
|
||||
|
@ -431,7 +453,7 @@ class Index extends PureComponent {
|
|||
</Dropdown>
|
||||
</div>
|
||||
</Drawer>
|
||||
</Fragment>
|
||||
</PageHeaderWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import {AutocompleteService} from '../../components/kibana/data/public/autocompl
|
|||
import {FilterManager} from '../../components/kibana/data/public/query/filter_manager/filter_manager';
|
||||
import {QueryStringManager} from '../../components/kibana/data/public/query/query_string/query_string_manager';
|
||||
import {Timefilter, TimeHistory} from '../../components/kibana/data/public/query/timefilter';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, createContext } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {buildEsQuery} from '../../components/kibana/data/common/es_query/es_query/build_es_query';
|
||||
import {getCalculateAutoTimeExpression} from '../../components/kibana/data/common/search/aggs/utils/calculate_auto_time_expression';
|
||||
|
|
|
@ -200,29 +200,28 @@ export default {
|
|||
message.success("添加文档成功")
|
||||
},
|
||||
*fetchIndices({payload}, {call, put}){
|
||||
let resp = yield call(getIndices)
|
||||
if(resp.status === false){
|
||||
let resp = yield call(getIndices, payload)
|
||||
if(resp.error){
|
||||
message.warn("获取数据失败")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
clusterIndices: resp.payload,
|
||||
cluster: payload.cluster,
|
||||
clusterIndices: resp,
|
||||
}
|
||||
})
|
||||
},
|
||||
*fetchMappings({payload}, {call, put}){
|
||||
let resp = yield call(getMappings, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("get mappings failed")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
mappings: resp.payload,
|
||||
mappings: resp,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,48 +11,48 @@ export default {
|
|||
},
|
||||
effects:{
|
||||
*fetchIndices({payload}, {call, put}){
|
||||
let resp = yield call(getIndices)
|
||||
if(resp.status === false){
|
||||
let resp = yield call(getIndices, payload)
|
||||
if(resp.error){
|
||||
message.warn("获取数据失败")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
clusterIndices: resp.payload,
|
||||
clusterIndices: resp,
|
||||
// cluster: payload.cluster,
|
||||
}
|
||||
})
|
||||
},
|
||||
*fetchMappings({payload}, {call, put}){
|
||||
let resp = yield call(getMappings, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("get mappings failed")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
mappings: resp.payload,
|
||||
mappings: resp,
|
||||
}
|
||||
})
|
||||
},
|
||||
*fetchSettings({payload}, {call, put}){
|
||||
let resp = yield call(getSettings, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("get settings failed")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
settings: resp.payload,
|
||||
settings: resp,
|
||||
}
|
||||
})
|
||||
},
|
||||
*saveSettings({payload}, {call, put, select}){
|
||||
let resp = yield call(updateSettings, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("save settings failed")
|
||||
return
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export default {
|
|||
},
|
||||
*removeIndex({payload}, {call, put, select}){
|
||||
let resp = yield call(deleteIndex, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("get mappings failed")
|
||||
return
|
||||
}
|
||||
|
@ -82,12 +82,15 @@ export default {
|
|||
},
|
||||
*addIndex({payload}, {call, put, select}){
|
||||
let resp = yield call(createIndex, payload);
|
||||
if(resp.status === false){
|
||||
if(resp.error){
|
||||
message.warn("create index failed")
|
||||
return
|
||||
}
|
||||
yield put({
|
||||
type: 'fetchIndices'
|
||||
type: 'fetchIndices',
|
||||
payload: {
|
||||
clusterID: payload.clusterID,
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
button {
|
||||
margin-right: 8px;
|
||||
}
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
message,
|
||||
Divider,
|
||||
Table, AutoComplete, Switch,
|
||||
Popconfirm
|
||||
} from 'antd';
|
||||
|
||||
import styles from '../../List/TableList.less';
|
||||
|
@ -18,42 +19,6 @@ import styles from '../../List/TableList.less';
|
|||
const FormItem = Form.Item;
|
||||
const { TextArea } = Input;
|
||||
|
||||
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, indices } = props;
|
||||
|
||||
|
@ -156,23 +121,28 @@ class AliasManage extends PureComponent {
|
|||
<Fragment>
|
||||
{/*<a onClick={() => this.handleUpdateModalVisible(true, record)}>别名设置</a>*/}
|
||||
{/*<Divider type="vertical" />*/}
|
||||
<a onClick={() => {
|
||||
let indices = [];
|
||||
for(let index of record.indexes){
|
||||
indices.push(index.index);
|
||||
}
|
||||
let vals = {
|
||||
alias: record.alias,
|
||||
indices,
|
||||
};
|
||||
this.handleDeleteClick(vals);
|
||||
}}>删除</a>
|
||||
<Popconfirm title="确定要删除?" onConfirm={()=>this.handleDeleteAliasClick(record)}> <a>删除</a></Popconfirm>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
];
|
||||
handleDeleteAliasClick = (record)=>{
|
||||
let indices = [];
|
||||
for(let index of record.indexes){
|
||||
indices.push(index.index);
|
||||
}
|
||||
let vals = {
|
||||
alias: record.alias,
|
||||
indices,
|
||||
};
|
||||
this.handleDeleteClick(vals);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchAliasList();
|
||||
this.fetchIndices();
|
||||
}
|
||||
fetchAliasList = ()=>{
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'alias/fetchAliasList',
|
||||
|
@ -181,6 +151,21 @@ class AliasManage extends PureComponent {
|
|||
}
|
||||
});
|
||||
}
|
||||
fetchIndices = ()=>{
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'alias/fetchIndices',
|
||||
payload: {
|
||||
clusterID: this.props.selectedClusterID,
|
||||
}
|
||||
});
|
||||
}
|
||||
componentDidUpdate(oldProps,newState,snapshot){
|
||||
if(oldProps.selectedClusterID != this.props.selectedClusterID){
|
||||
this.fetchAliasList();
|
||||
this.fetchIndices();
|
||||
}
|
||||
}
|
||||
|
||||
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
||||
|
||||
|
@ -320,6 +305,7 @@ class AliasManage extends PureComponent {
|
|||
if(this.state.keyword) {
|
||||
aliasList = aliasList.filter(al=>al.alias.includes(this.state.keyword))
|
||||
}
|
||||
const {indices} = this.props.alias;
|
||||
return (
|
||||
<Fragment>
|
||||
<Card bordered={false}>
|
||||
|
@ -329,11 +315,6 @@ class AliasManage extends PureComponent {
|
|||
<Button icon="plus" type="primary" onClick={() => this.handleUpdateModalVisible(true)}>
|
||||
新建
|
||||
</Button>
|
||||
{selectedRows.length > 0 && (
|
||||
<span>
|
||||
<Button onClick={() => this.handleDeleteClick()}>删除</Button>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<Table
|
||||
size="small"
|
||||
|
@ -345,8 +326,8 @@ class AliasManage extends PureComponent {
|
|||
return (
|
||||
<div>
|
||||
<AliasIndexTable rawData={record}
|
||||
handleDeleteClick={this.handleDeleteClick}
|
||||
handleUpdateModalVisible={this.handleUpdateModalVisible} data={record.indexes}/>
|
||||
handleDeleteClick={this.handleDeleteClick}
|
||||
handleUpdateModalVisible={this.handleUpdateModalVisible} data={record.indexes}/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
|
@ -360,7 +341,7 @@ class AliasManage extends PureComponent {
|
|||
{...updateMethods}
|
||||
updateModalVisible={updateModalVisible}
|
||||
values={updateFormValues}
|
||||
indices={['test-custom', 'dict']}
|
||||
indices={indices||[]}
|
||||
/>
|
||||
|
||||
</Fragment>
|
||||
|
@ -401,12 +382,13 @@ class AliasIndexTable extends React.Component {
|
|||
alias: this.props.rawData.alias,
|
||||
})}>设置</a>
|
||||
<Divider type="vertical" />
|
||||
<a onClick={() => {
|
||||
<Popconfirm title="确定要删除?" onConfirm={() => {
|
||||
this.props.handleDeleteClick({
|
||||
...record,
|
||||
alias: this.props.rawData.alias,
|
||||
});
|
||||
}}>删除</a>
|
||||
}}><a>删除</a>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
),
|
||||
},]
|
||||
|
@ -429,7 +411,7 @@ class IndexComplete extends React.Component {
|
|||
}
|
||||
}
|
||||
handleSearch = v => {
|
||||
let data = this.props.dataSource.filter(d=>d.includes(v));
|
||||
let data = this.props.dataSource.filter(d=>d.includes(v.replace(/\*$/, '')));
|
||||
// if(data.length > 0 && v.length >0) {
|
||||
// data.push(v+'*');
|
||||
// }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {getAliasList, doAlias } from '@/services/alias';
|
||||
import {getIndices } from '@/services/indices';
|
||||
|
||||
export default {
|
||||
namespace: 'alias',
|
||||
|
@ -19,6 +20,19 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
*fetchIndices({ payload }, { call, put }) {
|
||||
const res = yield call(getIndices, payload);
|
||||
let indices = [];
|
||||
for(let k in res){
|
||||
indices.push(k);
|
||||
}
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
indices,
|
||||
}
|
||||
})
|
||||
},
|
||||
*add({ payload, callback }, { call, put }) {
|
||||
|
||||
},
|
||||
|
|
|
@ -69,7 +69,6 @@ export default {
|
|||
return
|
||||
}
|
||||
resp.payload = formatESSearchResult(resp.payload);
|
||||
console.log(resp.payload);
|
||||
resp.payload.data = resp.payload.data.map((item)=>{
|
||||
item.content = utf8.decode(atob(item.content))
|
||||
return item;
|
||||
|
|
|
@ -17,7 +17,6 @@ export default {
|
|||
*fetchList({ payload }, { call, put , select }) {
|
||||
payload.cluster_id = yield select(state => state.global.selectedClusterID);
|
||||
const res = yield call(getTemplateList, payload);
|
||||
console.log("fetchList response:",res);
|
||||
if (res.hits) {
|
||||
let newList = [];
|
||||
let hits = res.hits.hits || [];
|
||||
|
|
|
@ -12,4 +12,6 @@ export function buildQueryArgs(params){
|
|||
argsStr = argsStr.slice(0, argsStr.length -1)
|
||||
}
|
||||
return argsStr;
|
||||
}
|
||||
}
|
||||
|
||||
export const ESPrefix = '/elasticsearch';
|
|
@ -1,12 +1,12 @@
|
|||
import request from '@/utils/request';
|
||||
import {pathPrefix} from './common';
|
||||
import {pathPrefix, ESPrefix} from './common';
|
||||
|
||||
export async function getDocList(params) {
|
||||
params.from = (params.pageIndex - 1) * params.pageSize;
|
||||
params.size = params.pageSize;
|
||||
delete params.pageSize;
|
||||
delete params.pageIndex;
|
||||
return request(`${pathPrefix}/doc/${params.index}/_search`, {
|
||||
return request(`${ESPrefix}/${params.clusterID}/doc/${params.index}/_search`, {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
});
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
import request from '@/utils/request';
|
||||
import {pathPrefix} from './common';
|
||||
import {pathPrefix, ESPrefix} from './common';
|
||||
|
||||
export async function getMappings(payload){
|
||||
let index = payload.index || '*'
|
||||
let url = `${pathPrefix}/index/${index}/_mappings`;
|
||||
export async function getMappings(params){
|
||||
let index = params.index || '*'
|
||||
let url = `${ESPrefix}/${params.clusterID}/index/${index}/_mappings`;
|
||||
return request(url,{
|
||||
method: 'GET',
|
||||
expirys: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSettings(payload){
|
||||
let index = payload.index || '*'
|
||||
let url = `${pathPrefix}/index/${index}/_settings`;
|
||||
export async function getSettings(params){
|
||||
let index = params.index || '*'
|
||||
let url = `${ESPrefix}/${params.clusterID}/index/${index}/_settings`;
|
||||
return request(url,{
|
||||
method: 'GET',
|
||||
expirys: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateSettings(payload){
|
||||
let index = payload.index
|
||||
let url = `${pathPrefix}/index/${index}/_settings`;
|
||||
export async function updateSettings(params){
|
||||
let index = params.index
|
||||
let url = `${ESPrefix}/${params.clusterID}/index/${index}/_settings`;
|
||||
return request(url,{
|
||||
method: 'PUT',
|
||||
body: payload.settings,
|
||||
body: params.settings,
|
||||
expirys: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getIndices(params) {
|
||||
return request(`${pathPrefix}/_cat/indices`, {
|
||||
return request(`${ESPrefix}/${params.clusterID}/_cat/indices`, {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteIndex(params) {
|
||||
let index = params.index;
|
||||
return request(`${pathPrefix}/index/${index}`, {
|
||||
return request(`${ESPrefix}/${params.clusterID}/index/${index}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ export async function deleteIndex(params) {
|
|||
|
||||
export async function createIndex(params) {
|
||||
let index = params.index;
|
||||
return request(`${pathPrefix}/index/${index}`, {
|
||||
return request(`${ESPrefix}/${params.clusterID}/index/${index}`, {
|
||||
method: 'POST',
|
||||
body: params.config
|
||||
});
|
||||
|
|
|
@ -2,9 +2,8 @@ import request from '@/utils/request';
|
|||
|
||||
|
||||
export async function getTemplateList(payload){
|
||||
let url = `/elasticsearch/${payload.cluster_id}/search_template/_search?from=${payload.from}&size=${payload.size}`;
|
||||
let url = `/elasticsearch/${payload.cluster_id}/search_template?from=${payload.from}&size=${payload.size}`;
|
||||
payload.name && (url+= `&name=${payload.name}`);
|
||||
console.log("url:",url);
|
||||
return request(url,{
|
||||
method: 'GET',
|
||||
// body: payload,
|
||||
|
|
Loading…
Reference in New Issue