cluster and command pagination and new metrics
This commit is contained in:
parent
2af1c743d4
commit
94dfeb9217
20
api/init.go
20
api/init.go
|
@ -1,9 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
log "github.com/cihub/seelog"
|
||||
"infini.sh/framework/core/api"
|
||||
"infini.sh/framework/core/task"
|
||||
"infini.sh/search-center/api/index_management"
|
||||
"infini.sh/search-center/config"
|
||||
"infini.sh/search-center/service/alerting"
|
||||
|
@ -79,14 +77,14 @@ func Init(cfg *config.AppConfig) {
|
|||
api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/_monitors/:monitorID/_acknowledge/alerts", alerting.AcknowledgeAlerts)
|
||||
|
||||
|
||||
task.RegisterScheduleTask(task.ScheduleTask{
|
||||
Description: "sync reindex task result",
|
||||
Task: func() {
|
||||
err := index_management.SyncRebuildResult(cfg.Elasticsearch)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
},
|
||||
})
|
||||
//task.RegisterScheduleTask(task.ScheduleTask{
|
||||
// Description: "sync reindex task result",
|
||||
// Task: func() {
|
||||
// err := index_management.SyncRebuildResult(cfg.Elasticsearch)
|
||||
// if err != nil {
|
||||
// log.Error(err)
|
||||
// }
|
||||
// },
|
||||
//})
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@ elasticsearch:
|
|||
- name: default
|
||||
enabled: true
|
||||
monitored: false
|
||||
endpoint: http://192.168.3.188:9299
|
||||
# endpoint: https://k8es.client.bindiego.com
|
||||
# basic_auth:
|
||||
# username: infini
|
||||
# password: BTxSrT5m33rfpF4
|
||||
endpoint: http://localhost:9200
|
||||
basic_auth:
|
||||
username: elastic
|
||||
password: ZBdkVQUUdF1Sir4X4BGB
|
||||
password: infinilabs
|
||||
|
||||
#前端 UI HTTP 配置
|
||||
web:
|
||||
|
|
|
@ -1,32 +1,46 @@
|
|||
// @ts-ignore
|
||||
import React, { useRef, useMemo,useEffect, useLayoutEffect, useState } from 'react';
|
||||
import ConsoleInput from './ConsoleInput';
|
||||
import ConsoleOutput from './ConsoleOutput';
|
||||
import { Panel } from './Panel';
|
||||
import PanelsContainer from './PanelContainer';
|
||||
import { PanelContextProvider } from '../contexts/panel_context';
|
||||
import { PanelRegistry } from '../contexts/panel_context/registry';
|
||||
import './Console.scss';
|
||||
import { RequestContextProvider, useRequestReadContext } from '../contexts/request_context';
|
||||
import {EditorContextProvider} from '../contexts/editor_context/editor_context';
|
||||
import { ServicesContextProvider } from '../contexts/services_context';
|
||||
import { createHistory, History, createStorage, createSettings } from '../services';
|
||||
import { create } from '../storage/local_storage_object_client';
|
||||
import { EuiFlexGroup, EuiFlexItem,EuiCodeBlock } from '@elastic/eui';
|
||||
import {RequestStatusBar} from './request_status_bar';
|
||||
import useEventListener from '@/lib/hooks/use_event_listener';
|
||||
import {Tabs} from 'antd';
|
||||
import React, {
|
||||
useRef,
|
||||
useMemo,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import ConsoleInput from "./ConsoleInput";
|
||||
import ConsoleOutput from "./ConsoleOutput";
|
||||
import { Panel } from "./Panel";
|
||||
import PanelsContainer from "./PanelContainer";
|
||||
import { PanelContextProvider } from "../contexts/panel_context";
|
||||
import { PanelRegistry } from "../contexts/panel_context/registry";
|
||||
import "./Console.scss";
|
||||
import {
|
||||
RequestContextProvider,
|
||||
useRequestReadContext,
|
||||
} from "../contexts/request_context";
|
||||
import { EditorContextProvider } from "../contexts/editor_context/editor_context";
|
||||
import { ServicesContextProvider } from "../contexts/services_context";
|
||||
import {
|
||||
createHistory,
|
||||
History,
|
||||
createStorage,
|
||||
createSettings,
|
||||
} from "../services";
|
||||
import { create } from "../storage/local_storage_object_client";
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiCodeBlock } from "@elastic/eui";
|
||||
import { RequestStatusBar } from "./request_status_bar";
|
||||
import useEventListener from "@/lib/hooks/use_event_listener";
|
||||
import { Tabs } from "antd";
|
||||
|
||||
interface props {
|
||||
selectedCluster: any;
|
||||
saveEditorContent: (content: string)=>void;
|
||||
saveEditorContent: (content: string) => void;
|
||||
initialText: string;
|
||||
paneKey: string;
|
||||
height: number;
|
||||
}
|
||||
|
||||
const INITIAL_PANEL_WIDTH = 50;
|
||||
const PANEL_MIN_WIDTH = '300px';
|
||||
const PANEL_MIN_WIDTH = "300px";
|
||||
|
||||
const ConsoleWrapper = ({
|
||||
selectedCluster,
|
||||
|
@ -34,7 +48,7 @@ const ConsoleWrapper = ({
|
|||
initialText,
|
||||
paneKey,
|
||||
height,
|
||||
}:props) => {
|
||||
}: props) => {
|
||||
const {
|
||||
requestInFlight: requestInProgress,
|
||||
lastResult: { data: requestData, error: requestError },
|
||||
|
@ -42,7 +56,7 @@ const ConsoleWrapper = ({
|
|||
|
||||
const lastDatum = requestData?.[requestData.length - 1] ?? requestError;
|
||||
|
||||
const calcHeight = height > 0 ? (height)+'px' : '100%';
|
||||
const calcHeight = height > 0 ? height + "px" : "100%";
|
||||
// const leftBarRef = useRef(null)
|
||||
// const rightBarRef = useRef(null)
|
||||
// const [widths, setWidths] = useState(['calc(50% - 7px)', 'calc(50% - 7px)'])
|
||||
|
@ -51,14 +65,39 @@ const ConsoleWrapper = ({
|
|||
// setWidths([lp+'%', rp+'%']);
|
||||
// }
|
||||
|
||||
return (
|
||||
<div style={{height: calcHeight}}>
|
||||
<div className="Console" style={{height:'100%'}}>
|
||||
<PanelsContainer resizerClassName="resizer">
|
||||
<Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH, paddingBottom:26 }} initialWidth={INITIAL_PANEL_WIDTH}>
|
||||
<ConsoleInput height={height-26+'px'} clusterID={selectedCluster.id} saveEditorContent={saveEditorContent} initialText={initialText} paneKey={paneKey} />
|
||||
<div style={{background:'#fff', position:'absolute', left:0, bottom:0, width: '100%', height:26, zIndex:997, borderTop: '1px solid #eee'}}>
|
||||
<RequestStatusBar
|
||||
return (
|
||||
<div style={{ height: calcHeight }}>
|
||||
<div className="Console" style={{ height: "100%" }}>
|
||||
<PanelsContainer resizerClassName="resizer">
|
||||
<Panel
|
||||
style={{
|
||||
height: "100%",
|
||||
position: "relative",
|
||||
minWidth: PANEL_MIN_WIDTH,
|
||||
paddingBottom: 26,
|
||||
}}
|
||||
initialWidth={INITIAL_PANEL_WIDTH}
|
||||
>
|
||||
<ConsoleInput
|
||||
height={height - 26 + "px"}
|
||||
clusterID={selectedCluster.id}
|
||||
saveEditorContent={saveEditorContent}
|
||||
initialText={initialText}
|
||||
paneKey={paneKey}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
background: "#fff",
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: "100%",
|
||||
height: 26,
|
||||
zIndex: 997,
|
||||
borderTop: "1px solid #eee",
|
||||
}}
|
||||
>
|
||||
<RequestStatusBar
|
||||
requestInProgress={requestInProgress}
|
||||
selectedCluster={selectedCluster}
|
||||
left={true}
|
||||
|
@ -69,40 +108,62 @@ const ConsoleWrapper = ({
|
|||
endpoint: lastDatum.request.path,
|
||||
statusCode: lastDatum.response.statusCode,
|
||||
statusText: lastDatum.response.statusText,
|
||||
timeElapsedMs: lastDatum.response.timeMs,
|
||||
requestHeader: lastDatum.request.header,
|
||||
responseHeader: lastDatum.response.header,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Panel>
|
||||
<Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH, paddingBottom:26 }} initialWidth={INITIAL_PANEL_WIDTH}>
|
||||
<Tabs tabPosition='right' style={{height:'100%', width:'100%'}} size="small">
|
||||
<Tabs.TabPane tab="Result" key="result">
|
||||
<div style={{height:height-26}}>
|
||||
<ConsoleOutput clusterID={selectedCluster.id} />
|
||||
</div>
|
||||
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Headers" key="headers">
|
||||
<Tabs animated={false}>
|
||||
<Tabs.TabPane tab="Request" key="1">
|
||||
<EuiCodeBlock language="text" isCopyable paddingSize="s">
|
||||
{lastDatum?.request.header}
|
||||
</EuiCodeBlock>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Response" key="2">
|
||||
<EuiCodeBlock language="text" isCopyable paddingSize="s">
|
||||
{lastDatum?.response.header}
|
||||
</EuiCodeBlock>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
<div style={{background:'#fff', position:'absolute', right:0, bottom:0, width: '100%', height:26, zIndex:997, borderTop: '1px solid #eee'}}>
|
||||
<RequestStatusBar
|
||||
timeElapsedMs: lastDatum.response.timeMs,
|
||||
requestHeader: lastDatum.request.header,
|
||||
responseHeader: lastDatum.response.header,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Panel>
|
||||
<Panel
|
||||
style={{
|
||||
height: "100%",
|
||||
position: "relative",
|
||||
minWidth: PANEL_MIN_WIDTH,
|
||||
paddingBottom: 26,
|
||||
}}
|
||||
initialWidth={INITIAL_PANEL_WIDTH}
|
||||
>
|
||||
<Tabs
|
||||
tabPosition="right"
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
size="small"
|
||||
>
|
||||
<Tabs.TabPane tab="Result" key="result">
|
||||
<div style={{ height: height - 26 }}>
|
||||
<ConsoleOutput clusterID={selectedCluster.id} />
|
||||
</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Headers" key="headers">
|
||||
<Tabs animated={false}>
|
||||
<Tabs.TabPane tab="Request" key="1">
|
||||
<EuiCodeBlock language="text" isCopyable paddingSize="s">
|
||||
{lastDatum?.request.header}
|
||||
</EuiCodeBlock>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Response" key="2">
|
||||
<EuiCodeBlock language="text" isCopyable paddingSize="s">
|
||||
{lastDatum?.response.header}
|
||||
</EuiCodeBlock>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
<div
|
||||
style={{
|
||||
background: "#fff",
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: "100%",
|
||||
height: 26,
|
||||
zIndex: 997,
|
||||
borderTop: "1px solid #eee",
|
||||
}}
|
||||
>
|
||||
<RequestStatusBar
|
||||
requestInProgress={requestInProgress}
|
||||
selectedCluster={selectedCluster}
|
||||
requestResult={
|
||||
|
@ -112,18 +173,18 @@ const ConsoleWrapper = ({
|
|||
endpoint: lastDatum.request.path,
|
||||
statusCode: lastDatum.response.statusCode,
|
||||
statusText: lastDatum.response.statusText,
|
||||
timeElapsedMs: lastDatum.response.timeMs,
|
||||
requestHeader: lastDatum.request.header,
|
||||
responseHeader: lastDatum.response.header,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Panel>
|
||||
</PanelsContainer>
|
||||
</div>
|
||||
{/* <div ref={statusBarRef} style={{ position:'fixed', bottom:0, borderTop: '1px solid #eee', zIndex:1001, width:'100%'}}>
|
||||
timeElapsedMs: lastDatum.response.timeMs,
|
||||
requestHeader: lastDatum.request.header,
|
||||
responseHeader: lastDatum.response.header,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Panel>
|
||||
</PanelsContainer>
|
||||
</div>
|
||||
{/* <div ref={statusBarRef} style={{ position:'fixed', bottom:0, borderTop: '1px solid #eee', zIndex:1001, width:'100%'}}>
|
||||
<div style={{background:'#fff',height:30, width:'100%'}}>
|
||||
<RequestStatusBar
|
||||
requestInProgress={requestInProgress}
|
||||
|
@ -145,38 +206,41 @@ const ConsoleWrapper = ({
|
|||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Console = (params:props) => {
|
||||
|
||||
const Console = (params: props) => {
|
||||
const registryRef = useRef(new PanelRegistry());
|
||||
// const [consoleInputKey] = useMemo(()=>{
|
||||
// return [selectedCluster.id + '-console-input'];
|
||||
// },[selectedCluster])
|
||||
|
||||
const {storage, history, objectStorageClient, settings} = useMemo(()=>{
|
||||
const { storage, history, objectStorageClient, settings } = useMemo(() => {
|
||||
const storage = createStorage({
|
||||
engine: window.localStorage,
|
||||
prefix: 'sense:',
|
||||
prefix: "sense:",
|
||||
});
|
||||
const history: History = createHistory({ storage });
|
||||
const objectStorageClient = create(storage);
|
||||
const settings = createSettings({storage});
|
||||
return {storage, history, objectStorageClient, settings};
|
||||
}, [])
|
||||
return ( <PanelContextProvider registry={registryRef.current}>
|
||||
<RequestContextProvider>
|
||||
<EditorContextProvider>
|
||||
<ServicesContextProvider value={{ services: { history, storage, objectStorageClient, settings}, clusterID: params.selectedCluster.id }}>
|
||||
const settings = createSettings({ storage });
|
||||
return { storage, history, objectStorageClient, settings };
|
||||
}, []);
|
||||
return (
|
||||
<PanelContextProvider registry={registryRef.current}>
|
||||
<RequestContextProvider>
|
||||
<EditorContextProvider>
|
||||
<ServicesContextProvider
|
||||
value={{
|
||||
services: { history, storage, objectStorageClient, settings },
|
||||
clusterID: params.selectedCluster.id,
|
||||
}}
|
||||
>
|
||||
<ConsoleWrapper {...params} />
|
||||
</ServicesContextProvider>
|
||||
</EditorContextProvider>
|
||||
</EditorContextProvider>
|
||||
</RequestContextProvider>
|
||||
</PanelContextProvider>
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
export default Console;
|
||||
|
||||
|
|
|
@ -166,8 +166,10 @@ const ConsoleInputUI = ({
|
|||
};
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
retrieveAutoCompleteInfo(settings, settings.getAutocomplete(), clusterID);
|
||||
aceEditorRef.current && (aceEditorRef.current["clusterID"] = clusterID);
|
||||
if (clusterID) {
|
||||
retrieveAutoCompleteInfo(settings, settings.getAutocomplete(), clusterID);
|
||||
aceEditorRef.current && (aceEditorRef.current["clusterID"] = clusterID);
|
||||
}
|
||||
}, [clusterID]);
|
||||
|
||||
const handleSaveAsCommonCommand = async () => {
|
||||
|
|
|
@ -30,58 +30,64 @@
|
|||
* GitHub history for details.
|
||||
*/
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { sendRequestToES } from './send_request_to_es';
|
||||
import { instance as registry } from '../../contexts/editor_context/editor_registry';
|
||||
import { useRequestActionContext } from '../../contexts/request_context';
|
||||
import { useServicesContext } from '../../contexts/services_context';
|
||||
import {getCommand} from '../../modules/mappings/mappings';
|
||||
import {useEditorReadContext} from '../../contexts/editor_context';
|
||||
import { useCallback } from "react";
|
||||
import { sendRequestToES } from "./send_request_to_es";
|
||||
import { instance as registry } from "../../contexts/editor_context/editor_registry";
|
||||
import { useRequestActionContext } from "../../contexts/request_context";
|
||||
import { useServicesContext } from "../../contexts/services_context";
|
||||
import { getCommand } from "../../modules/mappings/mappings";
|
||||
import { useEditorReadContext } from "../../contexts/editor_context";
|
||||
|
||||
function buildRawCommonCommandRequest(cmd:any){
|
||||
const {requests} = cmd._source;
|
||||
const strReqs = requests.map((req: any)=>{
|
||||
const {method, path, body} = req;
|
||||
function buildRawCommonCommandRequest(cmd: any) {
|
||||
const { requests } = cmd._source;
|
||||
const strReqs = requests.map((req: any) => {
|
||||
const { method, path, body } = req;
|
||||
return `${method} ${path}\n${body}`;
|
||||
})
|
||||
return strReqs.join('\n');
|
||||
});
|
||||
return strReqs.join("\n");
|
||||
}
|
||||
export const useSendCurrentRequestToES = () => {
|
||||
const dispatch = useRequestActionContext();
|
||||
const { services: { history }, clusterID } = useServicesContext();
|
||||
const {sensorEditor:editor} = useEditorReadContext();
|
||||
const {
|
||||
services: { history },
|
||||
clusterID,
|
||||
} = useServicesContext();
|
||||
const { sensorEditor: editor } = useEditorReadContext();
|
||||
|
||||
return useCallback(async () => {
|
||||
try {
|
||||
// const editor = registry.getInputEditor();
|
||||
if(!editor) return
|
||||
if (!editor) return;
|
||||
const requests = await editor.getRequestsInRange();
|
||||
if (!requests.length) {
|
||||
console.log('No request selected. Select a request by placing the cursor inside it.');
|
||||
console.log(
|
||||
"No request selected. Select a request by placing the cursor inside it."
|
||||
);
|
||||
return;
|
||||
}
|
||||
const {url, method, data} = requests[0];
|
||||
if(method === 'LOAD'){
|
||||
const rawUrl = data[0]? data[0].slice(4).trim(): url;
|
||||
const { url, method, data } = requests[0];
|
||||
if (method === "LOAD") {
|
||||
const rawUrl = data[0] ? data[0].slice(4).trim() : url;
|
||||
const cmd = getCommand(rawUrl);
|
||||
// const curPostion = editor.currentReqRange //(editor.getCoreEditor().getCurrentPosition());
|
||||
const lineNumber = editor.getCoreEditor().getCurrentPosition().lineNumber;
|
||||
let crange = await editor.getRequestRange(lineNumber)
|
||||
const rawRequest = buildRawCommonCommandRequest(cmd)
|
||||
// const curPostion = editor.currentReqRange //(editor.getCoreEditor().getCurrentPosition());
|
||||
const lineNumber = editor.getCoreEditor().getCurrentPosition()
|
||||
.lineNumber;
|
||||
let crange = await editor.getRequestRange(lineNumber);
|
||||
const rawRequest = buildRawCommonCommandRequest(cmd);
|
||||
await editor.getCoreEditor().replaceRange(crange as any, rawRequest);
|
||||
// await editor.autoIndent();
|
||||
// editor.getCoreEditor().getContainer().focus();
|
||||
// crange = await editor.getRequestRange(lineNumber)
|
||||
|
||||
|
||||
// editor.getCoreEditor().moveCursorToPosition({
|
||||
// ...crange?.end as any,
|
||||
// // column: editor.getCoreEditor().getLineValue(lineNumber).length + 1,
|
||||
// });
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({ type: 'sendRequest', payload: undefined });
|
||||
dispatch({ type: "sendRequest", payload: undefined });
|
||||
|
||||
// @ts-ignore
|
||||
const results = await sendRequestToES({ requests, clusterID });
|
||||
|
@ -104,20 +110,20 @@ export const useSendCurrentRequestToES = () => {
|
|||
// }
|
||||
//
|
||||
dispatch({
|
||||
type: 'requestSuccess',
|
||||
type: "requestSuccess",
|
||||
payload: {
|
||||
data: results,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e?.response) {
|
||||
if (e) {
|
||||
dispatch({
|
||||
type: 'requestFail',
|
||||
payload: e,
|
||||
type: "requestSuccess",
|
||||
payload: { data: [e] },
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'requestFail',
|
||||
type: "requestFail",
|
||||
payload: undefined,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
*/
|
||||
|
||||
// @ts-ignore
|
||||
import $ from 'jquery';
|
||||
import $ from "jquery";
|
||||
// @ts-ignore
|
||||
import { stringify } from 'query-string';
|
||||
import {pathPrefix, ESPrefix} from '@/services/common';
|
||||
import { stringify } from "query-string";
|
||||
import { pathPrefix, ESPrefix } from "@/services/common";
|
||||
|
||||
interface SendOptions {
|
||||
asSystemRequest?: boolean;
|
||||
|
@ -48,14 +48,14 @@ export function getVersion() {
|
|||
}
|
||||
|
||||
export function getContentType(body: unknown) {
|
||||
if (!body) return 'text/plain';
|
||||
return 'application/json';
|
||||
if (!body) return "text/plain";
|
||||
return "application/json";
|
||||
}
|
||||
|
||||
export function extractClusterIDFromURL(){
|
||||
export function extractClusterIDFromURL() {
|
||||
const matchs = location.hash.match(/\/elasticsearch\/(\w+)\/?/);
|
||||
if(!matchs){
|
||||
return ''
|
||||
if (!matchs) {
|
||||
return "";
|
||||
}
|
||||
return matchs[1];
|
||||
}
|
||||
|
@ -84,16 +84,20 @@ export function send(
|
|||
data,
|
||||
contentType: getContentType(data),
|
||||
cache: false,
|
||||
crossDomain: true,
|
||||
type: 'POST',
|
||||
dataType: 'json', // disable automatic guessing
|
||||
// crossDomain: true,
|
||||
type: "POST",
|
||||
dataType: "json", // disable automatic guessing
|
||||
};
|
||||
|
||||
$.ajax(options).then(
|
||||
(responseData: any, textStatus: string, jqXHR: unknown) => {
|
||||
wrappedDfd.resolveWith({}, [responseData, textStatus, jqXHR]);
|
||||
},
|
||||
((jqXHR: { status: number; responseText: string }, textStatus: string, errorThrown: Error) => {
|
||||
((
|
||||
jqXHR: { status: number; responseText: string },
|
||||
textStatus: string,
|
||||
errorThrown: Error
|
||||
) => {
|
||||
if (jqXHR.status === 0) {
|
||||
jqXHR.responseText =
|
||||
"\n\nFailed to connect to Console's backend.\nPlease check the server is up and running";
|
||||
|
@ -106,26 +110,26 @@ export function send(
|
|||
|
||||
export function queryCommonCommands(title?: string) {
|
||||
let url = `${pathPrefix}/elasticsearch/command`;
|
||||
if(title){
|
||||
url +=`?title=${title}`
|
||||
if (title) {
|
||||
url += `?title=${title}`;
|
||||
}
|
||||
return fetch(url, {
|
||||
method: 'GET',
|
||||
})
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
export function constructESUrl(baseUri: string, path: string) {
|
||||
baseUri = baseUri.replace(/\/+$/, '');
|
||||
path = path.replace(/^\/+/, '');
|
||||
return baseUri + '/' + path;
|
||||
baseUri = baseUri.replace(/\/+$/, "");
|
||||
path = path.replace(/^\/+/, "");
|
||||
return baseUri + "/" + path;
|
||||
}
|
||||
|
||||
export function saveCommonCommand(params: any) {
|
||||
return fetch(`${pathPrefix}/elasticsearch/command`, {
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
body: JSON.stringify(params),
|
||||
headers:{
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -207,8 +207,12 @@ export default {
|
|||
"Storage Usage",
|
||||
"dashboard.charts.title.cluster_storage.axis.available_storage":
|
||||
"Storage Available",
|
||||
"dashboard.charts.title.cluster_documents.axis.documents": "Documents Count",
|
||||
"dashboard.charts.title.cluster_documents.axis.count": "Documents Count",
|
||||
"dashboard.charts.title.cluster_documents.axis.deleted": "Docmuents Deleted",
|
||||
"dashboard.charts.title.cluster_indices.axis.count": "Indices Count",
|
||||
"dashboard.charts.title.cluster_documents.axis.counts": "Shards Count",
|
||||
"dashboard.charts.title.node_count.axis.count": "Nodes Count",
|
||||
"dashboard.charts.title.cluster_health.axis.percent": "Health Percent",
|
||||
|
||||
"app.login.message-invalid-credentials":
|
||||
"Invalid username or password(admin/888888)",
|
||||
|
|
|
@ -76,6 +76,13 @@ export default {
|
|||
"cluster.metrics.node.axis.docs_count.title": "Document Count",
|
||||
"cluster.metrics.node.axis.index_storage.title": "Indices Storage",
|
||||
"cluster.metrics.node.axis.jvm_heap_used_percent.title": "JVM Heap Usage",
|
||||
"cluster.metrics.node.axis.os_cpu.title": "OS CPU Percent",
|
||||
"cluster.metrics.node.axis.os_used_mem.title": "OS Mem Usage",
|
||||
"cluster.metrics.node.axis.indexing_pressure_memory.title":
|
||||
"Indexing Pressure",
|
||||
"cluster.metrics.node.axis.jvm_used_heap.title": "JVM Used Heap",
|
||||
"cluster.metrics.node.axis.jvm_young_gc_rate.title": "Young GC Rate",
|
||||
"cluster.metrics.node.axis.jvm_young_gc_latency.title": "Young GC Latency",
|
||||
|
||||
"cluster.metrics.index.axis.index_storage.title": "Index Storage",
|
||||
"cluster.metrics.index.axis.doc_count.title": "Document count",
|
||||
|
@ -105,4 +112,5 @@ export default {
|
|||
"cluster.metrics.group.http": "Http Traffic",
|
||||
"cluster.metrics.group.memory": "Memory",
|
||||
"cluster.metrics.group.cache": "Cache",
|
||||
"cluster.metrics.group.JVM": "JVM",
|
||||
};
|
||||
|
|
|
@ -6,7 +6,8 @@ export default {
|
|||
"navBar.lang": "语言",
|
||||
|
||||
"layout.user.appname": "极限数据管理后台",
|
||||
"layout.user.appslogon": "极限科技的数据管理平台是东半球最好用的实时数据管理平台",
|
||||
"layout.user.appslogon":
|
||||
"极限科技的数据管理平台是东半球最好用的实时数据管理平台",
|
||||
"app.setting.appname": "极限数据中心",
|
||||
|
||||
"layout.user.link.help": "帮助",
|
||||
|
@ -209,8 +210,12 @@ export default {
|
|||
|
||||
"dashboard.charts.title.cluster_storage.axis.indices_storage": "索引存储",
|
||||
"dashboard.charts.title.cluster_storage.axis.available_storage": "剩余存储",
|
||||
"dashboard.charts.title.node_count.axis.count": "节点数",
|
||||
"dashboard.charts.title.cluster_health.axis.percent": "健康状态百分比",
|
||||
|
||||
"dashboard.charts.title.cluster_documents.axis.documents": "文档总数",
|
||||
"dashboard.charts.title.cluster_documents.axis.count": "文档总数",
|
||||
"dashboard.charts.title.cluster_documents.axis.deleted": "文档删除数",
|
||||
"dashboard.charts.title.cluster_indices.axis.count": "索引总数",
|
||||
"dashboard.charts.title.cluster_documents.axis.counts": "分片总数",
|
||||
|
||||
"app.login.message-invalid-credentials": "账户或密码错误(admin/888888)",
|
||||
|
|
|
@ -77,6 +77,16 @@ export default {
|
|||
"cluster.metrics.node.axis.docs_count.title": "Document Count",
|
||||
"cluster.metrics.node.axis.index_storage.title": "Indices Storage",
|
||||
"cluster.metrics.node.axis.jvm_heap_used_percent.title": "JVM Heap Usage",
|
||||
"cluster.metrics.node.axis.os_cpu.title": "OS CPU Percent",
|
||||
"cluster.metrics.node.axis.os_used_mem.title": "OS Mem Usage",
|
||||
"cluster.metrics.node.axis.indexing_pressure_memory.title":
|
||||
"Indexing Pressure",
|
||||
"cluster.metrics.node.axis.jvm_used_heap.title": "JVM Used Heap",
|
||||
"cluster.metrics.node.axis.jvm_young_gc_rate.title": "Young GC Rate",
|
||||
"cluster.metrics.node.axis.jvm_young_gc_latency.title": "Young GC Latency",
|
||||
"cluster.metrics.node.axis.jvm_mem_young_used.title": "Pools Young Used",
|
||||
"cluster.metrics.node.axis.jvm_mem_young_peak_used.title":
|
||||
"Pools Young Peak Used",
|
||||
|
||||
"cluster.metrics.index.axis.index_storage.title": "Index Storage",
|
||||
"cluster.metrics.index.axis.doc_count.title": "Document count",
|
||||
|
@ -106,4 +116,5 @@ export default {
|
|||
"cluster.metrics.group.http": "Http Traffic",
|
||||
"cluster.metrics.group.memory": "Memory",
|
||||
"cluster.metrics.group.cache": "Cache",
|
||||
"cluster.metrics.group.JVM": "JVM",
|
||||
};
|
||||
|
|
|
@ -453,7 +453,7 @@ class ClusterMonitor extends PureComponent {
|
|||
});
|
||||
let clusterAvailable = true;
|
||||
const { clusterStatus: cstatus, selectedCluster } = this.props;
|
||||
if (cstatus && selectedCluster) {
|
||||
if (cstatus && selectedCluster && cstatus[selectedCluster.id]) {
|
||||
clusterAvailable = cstatus[selectedCluster.id].available;
|
||||
}
|
||||
|
||||
|
@ -674,6 +674,7 @@ class ClusterMonitor extends PureComponent {
|
|||
id={item.metric.label}
|
||||
groupId={item.metric.group}
|
||||
timeZone={timezone}
|
||||
color={item.color}
|
||||
xScaleType={ScaleType.Time}
|
||||
yScaleType={ScaleType.Linear}
|
||||
xAccessor={0}
|
||||
|
|
|
@ -28,6 +28,7 @@ const gorupOrder = [
|
|||
"latency",
|
||||
"storage",
|
||||
"http",
|
||||
"JVM",
|
||||
"memory",
|
||||
"cache",
|
||||
];
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useLayoutEffect,
|
||||
} from "react";
|
||||
import { useLocalStorage } from "@/lib/hooks/storage";
|
||||
import { setClusterID } from "../../components/kibana/console/modules/mappings/mappings";
|
||||
|
@ -116,6 +117,9 @@ const consoleTabReducer = (state: any, action: any) => {
|
|||
...state,
|
||||
order: action.payload.order,
|
||||
};
|
||||
break;
|
||||
case "init":
|
||||
newState = action.payload;
|
||||
default:
|
||||
}
|
||||
// setLocalState(newState);
|
||||
|
@ -199,11 +203,16 @@ export const ConsoleUI = ({
|
|||
});
|
||||
|
||||
if (panes.length == 0) {
|
||||
removeLocalState();
|
||||
//reset tabState
|
||||
dispatch({
|
||||
type: "init",
|
||||
payload: initialDefaultState(),
|
||||
});
|
||||
//removeLocalState();
|
||||
return;
|
||||
}
|
||||
setLocalState(tabState);
|
||||
}, [tabState, clusterMap]);
|
||||
}, [tabState, clusterMap, dispatch]);
|
||||
|
||||
const saveEditorContent = useCallback(
|
||||
(content) => {
|
||||
|
|
|
@ -1,29 +1,43 @@
|
|||
import React from 'react';
|
||||
import {Card, Form, Icon, Input, InputNumber, Button, Switch, message, Spin} from 'antd';
|
||||
import router from 'umi/router';
|
||||
import React from "react";
|
||||
import {
|
||||
Card,
|
||||
Form,
|
||||
Icon,
|
||||
Input,
|
||||
InputNumber,
|
||||
Button,
|
||||
Switch,
|
||||
message,
|
||||
Spin,
|
||||
} from "antd";
|
||||
import router from "umi/router";
|
||||
|
||||
import styles from './Form.less';
|
||||
import {connect} from "dva";
|
||||
import NewCluster from './Step';
|
||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||
import styles from "./Form.less";
|
||||
import { connect } from "dva";
|
||||
import NewCluster from "./Step";
|
||||
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
|
||||
|
||||
@Form.create()
|
||||
@connect(({clusterConfig}) =>({
|
||||
clusterConfig
|
||||
@connect(({ clusterConfig }) => ({
|
||||
clusterConfig,
|
||||
}))
|
||||
class ClusterForm extends React.Component{
|
||||
class ClusterForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
let editValue = this.props.clusterConfig.editValue;
|
||||
let needAuth = false;
|
||||
if(editValue.basic_auth && typeof editValue.basic_auth.username !== 'undefined' && editValue.basic_auth.username !== ''){
|
||||
if (
|
||||
editValue.basic_auth &&
|
||||
typeof editValue.basic_auth.username !== "undefined" &&
|
||||
editValue.basic_auth.username !== ""
|
||||
) {
|
||||
needAuth = true;
|
||||
}
|
||||
this.state = {
|
||||
confirmDirty: false,
|
||||
needAuth: needAuth,
|
||||
isLoading: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
//console.log(this.props.clusterConfig.editMode)
|
||||
|
@ -31,8 +45,8 @@ class ClusterForm extends React.Component{
|
|||
|
||||
compareToFirstPassword = (rule, value, callback) => {
|
||||
const { form } = this.props;
|
||||
if (value && value !== form.getFieldValue('password')) {
|
||||
callback('Two passwords that you enter is inconsistent!');
|
||||
if (value && value !== form.getFieldValue("password")) {
|
||||
callback("Two passwords that you enter is inconsistent!");
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
@ -41,16 +55,16 @@ class ClusterForm extends React.Component{
|
|||
validateToNextPassword = (rule, value, callback) => {
|
||||
const { form } = this.props;
|
||||
if (value && this.state.confirmDirty) {
|
||||
form.validateFields(['confirm'], { force: true });
|
||||
form.validateFields(["confirm"], { force: true });
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
handleSubmit = () =>{
|
||||
const {form, dispatch, clusterConfig} = this.props;
|
||||
handleSubmit = () => {
|
||||
const { form, dispatch, clusterConfig } = this.props;
|
||||
form.validateFields((errors, values) => {
|
||||
if(errors){
|
||||
return
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
//console.log(values);
|
||||
let newVals = {
|
||||
|
@ -64,76 +78,78 @@ class ClusterForm extends React.Component{
|
|||
enabled: values.enabled,
|
||||
monitored: values.monitored,
|
||||
version: values.version,
|
||||
schema: values.isTLS === true ? 'https': 'http',
|
||||
schema: values.isTLS === true ? "https" : "http",
|
||||
// order: values.order,
|
||||
}
|
||||
if(clusterConfig.editMode === 'NEW') {
|
||||
};
|
||||
if (clusterConfig.editMode === "NEW") {
|
||||
dispatch({
|
||||
type: 'clusterConfig/addCluster',
|
||||
type: "clusterConfig/addCluster",
|
||||
payload: newVals,
|
||||
}).then(function (rel){
|
||||
if(rel){
|
||||
message.success("添加成功")
|
||||
router.push('/system/cluster');
|
||||
}).then(function(rel) {
|
||||
if (rel) {
|
||||
message.success("添加成功");
|
||||
router.push("/system/cluster");
|
||||
}
|
||||
});
|
||||
}else{
|
||||
} else {
|
||||
newVals.id = clusterConfig.editValue.id;
|
||||
dispatch({
|
||||
type: 'clusterConfig/updateCluster',
|
||||
type: "clusterConfig/updateCluster",
|
||||
payload: newVals,
|
||||
}).then(function (rel){
|
||||
if(rel){
|
||||
message.success("修改成功")
|
||||
router.push('/system/cluster');
|
||||
}).then(function(rel) {
|
||||
if (rel) {
|
||||
message.success("修改成功");
|
||||
router.push("/system/cluster");
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
handleAuthChange = (val) => {
|
||||
this.setState({
|
||||
needAuth: val,
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
tryConnect = async ()=>{
|
||||
const {dispatch, form} = this.props;
|
||||
const values = await form.validateFields((errors, values) => {
|
||||
if(errors){
|
||||
tryConnect = async () => {
|
||||
const { dispatch, form } = this.props;
|
||||
const values = await form.validateFields((errors, values) => {
|
||||
if (errors) {
|
||||
return false;
|
||||
}
|
||||
let newVals = {
|
||||
name: values.name,
|
||||
host: values.host,
|
||||
basic_auth: {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
},
|
||||
schema: values.isTLS === true ? 'https': 'http',
|
||||
}
|
||||
|
||||
return values;
|
||||
});
|
||||
if(!values){
|
||||
return
|
||||
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
this.setState({isLoading: true})
|
||||
let newVals = {
|
||||
name: values.name,
|
||||
host: values.host,
|
||||
basic_auth: {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
},
|
||||
schema: values.isTLS === true ? "https" : "http",
|
||||
};
|
||||
this.setState({ isLoading: true });
|
||||
const res = await dispatch({
|
||||
type: 'clusterConfig/doTryConnect',
|
||||
payload: values
|
||||
type: "clusterConfig/doTryConnect",
|
||||
payload: newVals,
|
||||
});
|
||||
if(res){
|
||||
message.success('连接成功!')
|
||||
if (res) {
|
||||
message.success("连接成功!");
|
||||
form.setFieldsValue({
|
||||
version: res.version
|
||||
})
|
||||
version: res.version,
|
||||
});
|
||||
}
|
||||
this.setState({isLoading: false})
|
||||
}
|
||||
this.setState({ isLoading: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
|
@ -156,95 +172,105 @@ class ClusterForm extends React.Component{
|
|||
},
|
||||
},
|
||||
};
|
||||
const {editValue, editMode} = this.props.clusterConfig;
|
||||
const { editValue, editMode } = this.props.clusterConfig;
|
||||
return (
|
||||
<PageHeaderWrapper>
|
||||
<Card title={editMode === 'NEW' ? '注册集群': '修改集群配置'}
|
||||
extra={[<Button type="primary" onClick={()=>{
|
||||
router.push('/system/cluster');
|
||||
}}>返回</Button>]}
|
||||
>
|
||||
<Spin spinning={this.state.isLoading}>
|
||||
<Form {...formItemLayout}>
|
||||
<Form.Item label="集群名称">
|
||||
{getFieldDecorator('name', {
|
||||
initialValue: editValue.name,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
},
|
||||
],
|
||||
})(<Input autoComplete='off' placeholder="cluster-name" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="集群地址">
|
||||
{getFieldDecorator('host', {
|
||||
initialValue: editValue.host,
|
||||
rules: [
|
||||
{
|
||||
type: 'string',
|
||||
pattern: /^[\w\.]+\:\d+$/, //(https?:\/\/)?
|
||||
message: '请输入域名或 IP 地址和端口号',
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: '请输入域名或 IP 地址和端口号!',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="127.0.0.1:9200" />)}
|
||||
</Form.Item>
|
||||
<Form.Item style={{marginBottom:0}}>
|
||||
{getFieldDecorator('version', {
|
||||
initialValue: editValue.version,
|
||||
rules: [
|
||||
],
|
||||
})(<Input type="hidden"/>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="TLS">
|
||||
{getFieldDecorator('isTLS', {
|
||||
initialValue: editValue?.schema === "https",
|
||||
})(
|
||||
<Switch
|
||||
defaultChecked={editValue?.schema === "https"}
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否需要身份验证">
|
||||
<Switch
|
||||
defaultChecked={this.state.needAuth}
|
||||
onChange={this.handleAuthChange}
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>
|
||||
</Form.Item>
|
||||
{this.state.needAuth === true ? (<div>
|
||||
<Form.Item label="用户名">
|
||||
{getFieldDecorator('username', {
|
||||
initialValue: editValue.basic_auth?.username,
|
||||
rules: [
|
||||
],
|
||||
})(<Input autoComplete='off' />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="密码" hasFeedback>
|
||||
{getFieldDecorator('password', {
|
||||
initialValue: editValue.basic_auth?.password,
|
||||
rules: [
|
||||
],
|
||||
})(<Input.Password />)}
|
||||
</Form.Item>
|
||||
</div>):''}
|
||||
{/* <Form.Item label="排序权重">
|
||||
<PageHeaderWrapper>
|
||||
<Card
|
||||
title={editMode === "NEW" ? "注册集群" : "修改集群配置"}
|
||||
extra={[
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
router.push("/system/cluster");
|
||||
}}
|
||||
>
|
||||
返回
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<Spin spinning={this.state.isLoading}>
|
||||
<Form {...formItemLayout}>
|
||||
<Form.Item label="集群名称">
|
||||
{getFieldDecorator("name", {
|
||||
initialValue: editValue.name,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "Please input cluster name!",
|
||||
},
|
||||
],
|
||||
})(<Input autoComplete="off" placeholder="cluster-name" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="集群地址">
|
||||
{getFieldDecorator("host", {
|
||||
initialValue: editValue.host,
|
||||
rules: [
|
||||
{
|
||||
type: "string",
|
||||
pattern: /^[\w\.]+\:\d+$/, //(https?:\/\/)?
|
||||
message: "请输入域名或 IP 地址和端口号",
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: "请输入域名或 IP 地址和端口号!",
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="127.0.0.1:9200" />)}
|
||||
</Form.Item>
|
||||
<Form.Item style={{ marginBottom: 0 }}>
|
||||
{getFieldDecorator("version", {
|
||||
initialValue: editValue.version,
|
||||
rules: [],
|
||||
})(<Input type="hidden" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="TLS">
|
||||
{getFieldDecorator("isTLS", {
|
||||
initialValue: editValue?.schema === "https",
|
||||
})(
|
||||
<Switch
|
||||
defaultChecked={editValue?.schema === "https"}
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否需要身份验证">
|
||||
<Switch
|
||||
defaultChecked={this.state.needAuth}
|
||||
onChange={this.handleAuthChange}
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>
|
||||
</Form.Item>
|
||||
{this.state.needAuth === true ? (
|
||||
<div>
|
||||
<Form.Item label="用户名">
|
||||
{getFieldDecorator("username", {
|
||||
initialValue: editValue.basic_auth?.username,
|
||||
rules: [],
|
||||
})(<Input autoComplete="off" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="密码" hasFeedback>
|
||||
{getFieldDecorator("password", {
|
||||
initialValue: editValue.basic_auth?.password,
|
||||
rules: [],
|
||||
})(<Input.Password />)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{/* <Form.Item label="排序权重">
|
||||
{getFieldDecorator('order', {
|
||||
initialValue: editValue.order || 0,
|
||||
})(<InputNumber />)}
|
||||
</Form.Item> */}
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator('description', {
|
||||
initialValue: editValue.description,
|
||||
})(<Input.TextArea placeholder="集群应用描述" />)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="是否启用">
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator("description", {
|
||||
initialValue: editValue.description,
|
||||
})(<Input.TextArea placeholder="集群应用描述" />)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="是否启用">
|
||||
{getFieldDecorator('enabled', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: typeof editValue.enabled === 'undefined' ? true: editValue.enabled,
|
||||
|
@ -253,29 +279,34 @@ class ClusterForm extends React.Component{
|
|||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item> */}
|
||||
<Form.Item label="启用监控">
|
||||
{getFieldDecorator('monitored', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: typeof editValue.monitored === 'undefined' ? true: editValue.monitored,
|
||||
})(<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button type="primary" onClick={this.handleSubmit}>
|
||||
{editMode === 'NEW' ? '注册': '保存'}
|
||||
</Button>
|
||||
<Button style={{marginLeft: 15}} onClick={this.tryConnect}>
|
||||
测试连接
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Spin>
|
||||
</Card>
|
||||
<Form.Item label="启用监控">
|
||||
{getFieldDecorator("monitored", {
|
||||
valuePropName: "checked",
|
||||
initialValue:
|
||||
typeof editValue.monitored === "undefined"
|
||||
? true
|
||||
: editValue.monitored,
|
||||
})(
|
||||
<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button type="primary" onClick={this.handleSubmit}>
|
||||
{editMode === "NEW" ? "注册" : "保存"}
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 15 }} onClick={this.tryConnect}>
|
||||
测试连接
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Spin>
|
||||
</Card>
|
||||
</PageHeaderWrapper>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ClusterForm;
|
||||
export default ClusterForm;
|
||||
|
|
|
@ -214,13 +214,17 @@ class Index extends React.Component {
|
|||
});
|
||||
};
|
||||
componentDidMount() {
|
||||
this.fetchData({});
|
||||
const { pageSize } = this.props.clusterConfig;
|
||||
this.fetchData({
|
||||
size: pageSize,
|
||||
});
|
||||
}
|
||||
|
||||
handleSearchClick = () => {
|
||||
const { form } = this.props;
|
||||
this.fetchData({
|
||||
name: form.getFieldValue("name"),
|
||||
current: 1,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -268,6 +272,17 @@ class Index extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
handleTableChange = (pagination, filters, sorter, extra) => {
|
||||
const { form } = this.props;
|
||||
const { pageSize, current } = pagination;
|
||||
this.fetchData({
|
||||
from: (current - 1) * pageSize,
|
||||
size: pageSize,
|
||||
name: form.getFieldValue("name"),
|
||||
current,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const formItemLayout = {
|
||||
|
@ -275,7 +290,7 @@ class Index extends React.Component {
|
|||
wrapperCol: { span: 14 },
|
||||
style: { marginBottom: 0 },
|
||||
};
|
||||
const { data } = this.props.clusterConfig;
|
||||
const { total, data, pageSize, current } = this.props.clusterConfig;
|
||||
return (
|
||||
<PageHeaderWrapper
|
||||
title={formatMessage({ id: "cluster.manage.title" })}
|
||||
|
@ -342,7 +357,13 @@ class Index extends React.Component {
|
|||
bordered
|
||||
columns={this.columns}
|
||||
dataSource={data}
|
||||
onChange={this.handleTableChange}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
pageSize: pageSize,
|
||||
total: total?.value || total,
|
||||
current: current,
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</PageHeaderWrapper>
|
||||
|
|
|
@ -13,6 +13,8 @@ export default {
|
|||
state: {
|
||||
editMode: "",
|
||||
editValue: {},
|
||||
pageSize: 20,
|
||||
current: 1,
|
||||
},
|
||||
effects: {
|
||||
*fetchClusterList({ payload }, { call, put, select }) {
|
||||
|
@ -28,7 +30,10 @@ export default {
|
|||
// }
|
||||
yield put({
|
||||
type: "saveData",
|
||||
payload: res,
|
||||
payload: {
|
||||
...res,
|
||||
current: payload.current,
|
||||
},
|
||||
});
|
||||
},
|
||||
*addCluster({ payload }, { call, put, select }) {
|
||||
|
|
|
@ -113,7 +113,9 @@ class Index extends PureComponent {
|
|||
];
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchData();
|
||||
this.fetchData({
|
||||
current: 1,
|
||||
});
|
||||
}
|
||||
|
||||
fetchData = (params = {}) => {
|
||||
|
@ -159,6 +161,7 @@ class Index extends PureComponent {
|
|||
keyword: fieldsValue.keyword,
|
||||
from: 0,
|
||||
size: 10,
|
||||
current: 1,
|
||||
});
|
||||
this.setState({
|
||||
searchKey: fieldsValue.keyword,
|
||||
|
@ -231,9 +234,19 @@ class Index extends PureComponent {
|
|||
},
|
||||
});
|
||||
};
|
||||
handleTableChange = (pagination, filters, sorter, extra) => {
|
||||
const { form } = this.props;
|
||||
const { pageSize, current } = pagination;
|
||||
this.fetchData({
|
||||
from: (current - 1) * pageSize,
|
||||
size: pageSize,
|
||||
keyword: form.getFieldValue("keyword"),
|
||||
current,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, total } = this.props.command;
|
||||
const { data, total, pageSize, current } = this.props.command;
|
||||
const {
|
||||
modalVisible,
|
||||
updateModalVisible,
|
||||
|
@ -301,7 +314,12 @@ class Index extends PureComponent {
|
|||
bordered
|
||||
dataSource={data}
|
||||
rowKey="id"
|
||||
pagination={{ pageSize: 10 }}
|
||||
pagination={{
|
||||
pageSize: pageSize,
|
||||
current: current,
|
||||
total: total?.value || total,
|
||||
}}
|
||||
onChange={this.handleTableChange}
|
||||
columns={this.columns}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,10 @@ import { formatESSearchResult } from "@/lib/elasticsearch/util";
|
|||
|
||||
export default {
|
||||
namespace: "command",
|
||||
state: {},
|
||||
state: {
|
||||
pageSize: 20,
|
||||
current: 1,
|
||||
},
|
||||
effects: {
|
||||
*fetchCommandList({ payload }, { call, put, select }) {
|
||||
let res = yield call(searchCommand, payload);
|
||||
|
@ -15,7 +18,10 @@ export default {
|
|||
res = formatESSearchResult(res);
|
||||
yield put({
|
||||
type: "saveData",
|
||||
payload: res,
|
||||
payload: {
|
||||
...res,
|
||||
current: payload.current,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue