Merge branch 'master' of ssh://git.infini.ltd:64221/infini/search-center

This commit is contained in:
shiyang 2021-10-29 17:44:57 +08:00
commit c7af0059f1
24 changed files with 210 additions and 229 deletions

View File

@ -4,7 +4,6 @@ import (
log "github.com/cihub/seelog" log "github.com/cihub/seelog"
"infini.sh/framework/core/api" "infini.sh/framework/core/api"
"infini.sh/framework/core/task" "infini.sh/framework/core/task"
"infini.sh/framework/core/ui"
"infini.sh/search-center/api/index_management" "infini.sh/search-center/api/index_management"
"infini.sh/search-center/config" "infini.sh/search-center/config"
"infini.sh/search-center/service/alerting" "infini.sh/search-center/service/alerting"
@ -17,66 +16,66 @@ func Init(cfg *config.AppConfig) {
} }
var pathPrefix = "/_search-center/" var pathPrefix = "/_search-center/"
var esPrefix = "/elasticsearch/:id/" var esPrefix = "/elasticsearch/:id/"
//ui.HandleUIMethod(api.POST, "/api/get_indices",index_management.API1) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/overview"), handler.ElasticsearchOverviewAction)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/overview"), handler.ElasticsearchOverviewAction) //api.HandleAPIMethod(api.POST, "/api/get_indices",index_management.API1)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "dict/_search"), handler.GetDictListAction) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "dict/_search"), handler.GetDictListAction)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "dict/*id"), handler.CreateDictItemAction) api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "dict/*id"), handler.CreateDictItemAction)
//ui.HandleUIMethod(api.GET, "/api/dict/:id",handler.GetDictItemAction) //api.HandleAPIMethod(api.GET, "/api/dict/:id",handler.GetDictItemAction)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "dict/:id"), handler.DeleteDictItemAction) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "dict/:id"), handler.DeleteDictItemAction)
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix, "dict/:id"), handler.UpdateDictItemAction) api.HandleAPIMethod(api.PUT, path.Join(pathPrefix, "dict/:id"), handler.UpdateDictItemAction)
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "doc/:index/_search"), handler.HandleSearchDocumentAction) api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index/_search"), handler.HandleSearchDocumentAction)
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "doc/:index"), handler.HandleAddDocumentAction) api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index"), handler.HandleAddDocumentAction)
ui.HandleUIMethod(api.PUT, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleUpdateDocumentAction) api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleUpdateDocumentAction)
ui.HandleUIMethod(api.DELETE, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleDeleteDocumentAction) api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleDeleteDocumentAction)
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "doc/_validate"), handler.ValidateDocIDAction) api.HandleAPIMethod(api.GET, path.Join(esPrefix, "doc/_validate"), handler.ValidateDocIDAction)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "rebuild/*id"), handler.HandleReindexAction) api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "rebuild/*id"), handler.HandleReindexAction)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "rebuild/_search"), handler.HandleGetRebuildListAction) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "rebuild/_search"), handler.HandleGetRebuildListAction)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "rebuild/:id"), handler.HandleDeleteRebuildAction) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "rebuild/:id"), handler.HandleDeleteRebuildAction)
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "_cat/indices"), handler.HandleGetIndicesAction) api.HandleAPIMethod(api.GET, path.Join(esPrefix, "_cat/indices"), handler.HandleGetIndicesAction)
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "index/:index/_mappings"), handler.HandleGetMappingsAction) api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_mappings"), handler.HandleGetMappingsAction)
ui.HandleUIMethod(api.GET, path.Join(esPrefix, "index/:index/_settings"), handler.HandleGetSettingsAction) api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_settings"), handler.HandleGetSettingsAction)
ui.HandleUIMethod(api.PUT, path.Join(esPrefix, "index/:index/_settings"), handler.HandleUpdateSettingsAction) api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "index/:index/_settings"), handler.HandleUpdateSettingsAction)
ui.HandleUIMethod(api.DELETE, path.Join(esPrefix, "index/:index"), handler.HandleDeleteIndexAction) api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "index/:index"), handler.HandleDeleteIndexAction)
ui.HandleUIMethod(api.POST, path.Join(esPrefix, "index/:index"), handler.HandleCreateIndexAction) api.HandleAPIMethod(api.POST, path.Join(esPrefix, "index/:index"), handler.HandleCreateIndexAction)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleSaveCommonCommandAction) api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleSaveCommonCommandAction)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleQueryCommonCommandAction) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleQueryCommonCommandAction)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleDeleteCommonCommandAction) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleDeleteCommonCommandAction)
//new api //new api
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "alerting/overview"), alerting.GetAlertOverview) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "alerting/overview"), alerting.GetAlertOverview)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "alerting/overview/alerts"), alerting.GetAlerts) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "alerting/overview/alerts"), alerting.GetAlerts)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations/email_accounts"), alerting.CreateEmailAccount) api.HandleAPIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations/email_accounts"), alerting.CreateEmailAccount)
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix, "alerting/email_accounts/:emailAccountId"), alerting.UpdateEmailAccount) api.HandleAPIMethod(api.PUT, path.Join(pathPrefix, "alerting/email_accounts/:emailAccountId"), alerting.UpdateEmailAccount)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix,"alerting/email_accounts/:emailAccountId"), alerting.DeleteEmailAccount) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix,"alerting/email_accounts/:emailAccountId"), alerting.DeleteEmailAccount)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix,"alerting/destinations/email_accounts"), alerting.GetEmailAccounts) api.HandleAPIMethod(api.GET, path.Join(pathPrefix,"alerting/destinations/email_accounts"), alerting.GetEmailAccounts)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix,"alerting/email_accounts/:emailAccountId"), alerting.GetEmailAccount) api.HandleAPIMethod(api.GET, path.Join(pathPrefix,"alerting/email_accounts/:emailAccountId"), alerting.GetEmailAccount)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations/email_groups"), alerting.CreateEmailGroup) api.HandleAPIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations/email_groups"), alerting.CreateEmailGroup)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix,"alerting/destinations/email_groups"), alerting.GetEmailGroups) api.HandleAPIMethod(api.GET, path.Join(pathPrefix,"alerting/destinations/email_groups"), alerting.GetEmailGroups)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.DeleteEmailGroup) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.DeleteEmailGroup)
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.UpdateEmailGroup) api.HandleAPIMethod(api.PUT, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.UpdateEmailGroup)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.GetEmailGroup) api.HandleAPIMethod(api.GET, path.Join(pathPrefix,"alerting/email_groups/:emailGroupId"), alerting.GetEmailGroup)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix, "alerting/destinations"), alerting.GetDestinations) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "alerting/destinations"), alerting.GetDestinations)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations"), alerting.CreateDestination) api.HandleAPIMethod(api.POST, path.Join(pathPrefix,"alerting/destinations"), alerting.CreateDestination)
ui.HandleUIMethod(api.PUT, path.Join(pathPrefix,"alerting/destinations/:destinationId"), alerting.UpdateDestination) api.HandleAPIMethod(api.PUT, path.Join(pathPrefix,"alerting/destinations/:destinationId"), alerting.UpdateDestination)
ui.HandleUIMethod(api.DELETE, path.Join(pathPrefix, "alerting/destinations/:destinationId"), alerting.DeleteDestination) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "alerting/destinations/:destinationId"), alerting.DeleteDestination)
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.GetMonitor) api.HandleAPIMethod(api.GET, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.GetMonitor)
ui.HandleUIMethod(api.PUT, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.UpdateMonitor) api.HandleAPIMethod(api.PUT, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.UpdateMonitor)
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/monitors", alerting.GetMonitors) api.HandleAPIMethod(api.GET, "/elasticsearch/:id/alerting/monitors", alerting.GetMonitors)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/monitors", alerting.CreateMonitor) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/monitors", alerting.CreateMonitor)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/monitors/_execute", alerting.ExecuteMonitor) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/monitors/_execute", alerting.ExecuteMonitor)
ui.HandleUIMethod(api.DELETE, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.DeleteMonitor) api.HandleAPIMethod(api.DELETE, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.DeleteMonitor)
ui.HandleUIMethod(api.GET, path.Join(pathPrefix,"alerting/_settings"), alerting.GetSettings) api.HandleAPIMethod(api.GET, path.Join(pathPrefix,"alerting/_settings"), alerting.GetSettings)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_indices", alerting.GetIndices) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/_indices", alerting.GetIndices)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_aliases", alerting.GetAliases) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/_aliases", alerting.GetAliases)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_mappings", alerting.GetMappings) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/_mappings", alerting.GetMappings)
ui.HandleUIMethod(api.POST, path.Join(pathPrefix, "alerting/_search"), alerting.Search) api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "alerting/_search"), alerting.Search)
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/alerts", alerting.GetAlerts) api.HandleAPIMethod(api.GET, "/elasticsearch/:id/alerting/alerts", alerting.GetAlerts)
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_monitors/:monitorID/_acknowledge/alerts", alerting.AcknowledgeAlerts) api.HandleAPIMethod(api.POST, "/elasticsearch/:id/alerting/_monitors/:monitorID/_acknowledge/alerts", alerting.AcknowledgeAlerts)
task.RegisterScheduleTask(task.ScheduleTask{ task.RegisterScheduleTask(task.ScheduleTask{

View File

@ -67,6 +67,14 @@ func main() {
appUI = &UI{Config: appConfig} appUI = &UI{Config: appConfig}
appUI.InitUI() appUI.InitUI()
//uiConfig := ui.UIConfig{}
//env.ParseConfig("web", &uiConfig)
//
//if len(global.Env().SystemConfig.APIConfig.CrossDomain.AllowedOrigins)==0{
// global.Env().SystemConfig.APIConfig.CrossDomain.AllowedOrigins=
// append(global.Env().SystemConfig.APIConfig.CrossDomain.AllowedOrigins,uiConfig.NetworkConfig.GetBindingAddr())
//}
//start each module, with enabled provider //start each module, with enabled provider
module.Start() module.Start()

View File

@ -49,6 +49,8 @@ export default {
}, },
define: { define: {
APP_TYPE: process.env.APP_TYPE || '', APP_TYPE: process.env.APP_TYPE || '',
ENV: process.env.NODE_ENV,
API_ENDPOINT: 'http://localhost:2900',
}, },
// 路由配置 // 路由配置
routes: pageRoutes, routes: pageRoutes,

View File

@ -482,7 +482,7 @@ export default [
}, },
{ {
path: '/system/command', path: '/system/command',
name: 'command', name: 'commonCommand',
component: './System/Command/Index', component: './System/Command/Index',
hideInMenu: true hideInMenu: true
}, },

View File

@ -127,3 +127,7 @@ i.trigger {
} }
} }
} }
[tabindex]{
outline: none !important;
}

View File

@ -1,5 +1,5 @@
// @ts-ignore // @ts-ignore
import React, { useRef, useMemo,useEffect, useLayoutEffect } from 'react'; import React, { useRef, useMemo,useEffect, useLayoutEffect, useState } from 'react';
import ConsoleInput from './ConsoleInput'; import ConsoleInput from './ConsoleInput';
import ConsoleOutput from './ConsoleOutput'; import ConsoleOutput from './ConsoleOutput';
import { Panel } from './Panel'; import { Panel } from './Panel';
@ -40,61 +40,68 @@ const ConsoleWrapper = ({
} = useRequestReadContext(); } = useRequestReadContext();
const lastDatum = requestData?.[requestData.length - 1] ?? requestError; const lastDatum = requestData?.[requestData.length - 1] ?? requestError;
const getElementTop = (elem: any)=>{
  var elemTop=elem.offsetTop;
  elem=elem.offsetParent;
  while(elem!=null){
    elemTop+=elem.offsetTop;
    elem=elem.offsetParent;
  }
  return elemTop;
}
const statusBarRef = useRef<HTMLDivElement>(null);
const consoleRef = useRef<HTMLDivElement>(null);
// useEffect(()=>{ const calcHeight = height > 0 ? (height)+'px' : '100%';
// const winScroll = ()=>{ // const leftBarRef = useRef(null)
// const wsTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; // const rightBarRef = useRef(null)
// if(wsTop>getElementTop(consoleRef.current)) { // const [widths, setWidths] = useState(['calc(50% - 7px)', 'calc(50% - 7px)'])
// statusBarRef.current && (statusBarRef.current.style.position='relative'); // const onPanelWidthChange = (widths:any)=>{
// }else{ // const [lp, rp] = widths;
// statusBarRef.current && (statusBarRef.current.style.position='fixed'); // setWidths([lp+'%', rp+'%']);
// } // }
// }
// window.addEventListener('scroll', winScroll, {passive:true})
// return ()=>{
// window.removeEventListener('scroll', winScroll)
// }
// },[])
useEventListener('resize', ()=>{
statusBarRef.current && consoleRef.current && (statusBarRef.current.style.width=consoleRef.current.offsetWidth+'px');
})
useLayoutEffect(()=>{
// console.log(consoleRef.current?.offsetWidth)
if(consoleRef.current.offsetWidth>0)
statusBarRef.current && consoleRef.current && (statusBarRef.current.style.width=consoleRef.current.offsetWidth+'px');
}, [consoleRef.current?.offsetWidth])
const calcHeight = height > 0 ? (height-35)+'px' : '100%';
return ( return (
<div style={{height: calcHeight}}> <div style={{height: calcHeight}}>
<div ref={consoleRef} className="Console" style={{height:'100%'}}> <div className="Console" style={{height:'100%'}}>
<PanelsContainer resizerClassName="resizer"> <PanelsContainer resizerClassName="resizer">
<Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH }} initialWidth={INITIAL_PANEL_WIDTH}> <Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH, paddingBottom:30 }} initialWidth={INITIAL_PANEL_WIDTH}>
<ConsoleInput clusterID={selectedCluster.id} saveEditorContent={saveEditorContent} initialText={initialText} paneKey={paneKey} /> <ConsoleInput clusterID={selectedCluster.id} saveEditorContent={saveEditorContent} initialText={initialText} paneKey={paneKey} />
<div style={{background:'#fff', position:'absolute', left:0, bottom:0, width: '100%', height:30, zIndex:1001, borderTop: '1px solid #eee'}}>
<RequestStatusBar
requestInProgress={requestInProgress}
selectedCluster={selectedCluster}
left={true}
requestResult={
lastDatum
? {
method: lastDatum.request.method.toUpperCase(),
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>
<Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH }} initialWidth={INITIAL_PANEL_WIDTH}> <Panel style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH, paddingBottom:30 }} initialWidth={INITIAL_PANEL_WIDTH}>
<ConsoleOutput clusterID={selectedCluster.id} /> <ConsoleOutput clusterID={selectedCluster.id} />
<div style={{background:'#fff', position:'absolute', right:0, bottom:0, width: '100%', height:30, zIndex:1001, borderTop: '1px solid #eee'}}>
<RequestStatusBar
requestInProgress={requestInProgress}
selectedCluster={selectedCluster}
requestResult={
lastDatum
? {
method: lastDatum.request.method.toUpperCase(),
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>
</PanelsContainer> </PanelsContainer>
</div> </div>
<div ref={statusBarRef} style={{ position:'fixed', bottom:0, borderTop: '1px solid #eee', zIndex:1001, width:'100%'}}> {/* <div ref={statusBarRef} style={{ position:'fixed', bottom:0, borderTop: '1px solid #eee', zIndex:1001, width:'100%'}}>
<div style={{background:'#fff',height:30, width:'100%'}}> <div style={{background:'#fff',height:30, width:'100%'}}>
<RequestStatusBar <RequestStatusBar
requestInProgress={requestInProgress} requestInProgress={requestInProgress}
@ -115,7 +122,7 @@ const ConsoleWrapper = ({
} }
/> />
</div> </div>
</div> </div> */}
</div> </div>
); );
}; };

View File

@ -1,15 +1,14 @@
.request-status-bar{ .request-status-bar{
display: flex;
justify-content: center;
align-items: center;
height: 100%; height: 100%;
.bar-item{ .bar-item{
flex: 0 0 50%; height: 100%;
.base-info{ .base-info{
display: flex; display: flex;
font-size: 12px; font-size: 12px;
align-items: center;
margin-top: 2px;
.info-item{ .info-item{
margin: 12px; margin: 0 12px;
position: relative; position: relative;
&.health{ &.health{
padding-right: 14px; padding-right: 14px;
@ -21,7 +20,7 @@
font-size: 12px; font-size: 12px;
align-items: center; align-items: center;
.info-item{ .info-item{
margin: 12px; margin: 0 12px;
} }
} }
} }

View File

@ -22,6 +22,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiText, EuiToolTip,EuiCodeBlock }
import {HealthStatusCircle} from '@/components/infini/health_status_circle'; import {HealthStatusCircle} from '@/components/infini/health_status_circle';
import './request_status_bar.scss'; import './request_status_bar.scss';
import {Drawer, Tabs, Button} from 'antd'; import {Drawer, Tabs, Button} from 'antd';
import { FormattedMessage, formatMessage } from 'umi/locale';
export interface Props { export interface Props {
requestInProgress: boolean; requestInProgress: boolean;
@ -65,101 +66,27 @@ const mapStatusCodeToBadgeColor = (statusCode: number) => {
return 'danger'; return 'danger';
}; };
// export const RequestStatusBar: FunctionComponent<Props> = ({
// requestInProgress,
// requestResult,
// selectedCluster,
// }) => {
// let content: React.ReactNode = null;
// const clusterContent = (<EuiFlexItem grow={false} style={{marginRight:'auto'}}>
// <EuiBadge style={{position:'relative', paddingLeft: 20}}>
// <i style={{marginRight:3, position:'absolute', top: 1, left:3}}><HealthStatusCircle status={selectedCluster.status}/></i>{selectedCluster.host}&nbsp;-&nbsp;{selectedCluster.version}
// </EuiBadge>
// </EuiFlexItem>);
// if (requestInProgress) {
// content = (
// <EuiFlexItem grow={false}>
// <EuiBadge color="hollow">
// Request in progress
// </EuiBadge>
// </EuiFlexItem>
// );
// } else if (requestResult) {
// const { endpoint, method, statusCode, statusText, timeElapsedMs } = requestResult;
// content = (
// <>
// <EuiFlexItem grow={false}>
// <EuiToolTip
// position="top"
// content={
// <EuiText size="s">{`${method} ${
// endpoint.startsWith('/') ? endpoint : '/' + endpoint
// }`}</EuiText>
// }
// >
// <EuiBadge color={mapStatusCodeToBadgeColor(statusCode)}>
// {/* Use &nbsp; to ensure that no matter the width we don't allow line breaks */}
// {statusCode}&nbsp;-&nbsp;{statusText}
// </EuiBadge>
// </EuiToolTip>
// </EuiFlexItem>
// <EuiFlexItem grow={false}>
// <EuiToolTip
// position="top"
// content={
// <EuiText size="s">
// Time Elapsed
// </EuiText>
// }
// >
// <EuiText size="s">
// <EuiBadge color="default">
// {timeElapsedMs}&nbsp;{'ms'}
// </EuiBadge>
// </EuiText>
// </EuiToolTip>
// </EuiFlexItem>
// </>
// );
// }
// return (
// <EuiFlexGroup
// justifyContent="flexEnd"
// alignItems="center"
// direction="row"
// gutterSize="s"
// responsive={false}
// >
// {clusterContent}
// {content}
// </EuiFlexGroup>
// );
// };
export const RequestStatusBar = ({ export const RequestStatusBar = ({
requestInProgress, requestInProgress,
requestResult, requestResult,
selectedCluster, selectedCluster,
container, left,
}:Props) => { }:Props) => {
let content: React.ReactNode = null; let content: React.ReactNode = null;
const clusterContent = (<div className="base-info"> const clusterContent = (<div className="base-info">
<div className="info-item health"> <div className="info-item health">
<span></span> <span> <FormattedMessage id="console.cluster.status"/></span>
<i style={{position:'absolute', top: 1, right:0}}> <i style={{position:'absolute', top: 1, right:0}}>
<HealthStatusCircle status={selectedCluster.status}/> <HealthStatusCircle status={selectedCluster.status}/>
</i> </i>
</div> </div>
<div className="info-item"> <div className="info-item">
<span></span> <span><FormattedMessage id="console.cluster.endpoint"/></span>
<EuiBadge color="default">{selectedCluster.host}</EuiBadge> <EuiBadge color="default">{selectedCluster.host}</EuiBadge>
</div> </div>
<div className="info-item"> <div className="info-item">
<span></span> <span><FormattedMessage id="console.cluster.version"/></span>
<EuiBadge color="default"> {selectedCluster.version}</EuiBadge> <EuiBadge color="default">{selectedCluster.version}</EuiBadge>
</div> </div>
</div>); </div>);
const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false) const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
@ -179,7 +106,7 @@ const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
<> <>
<div className="status_info"> <div className="status_info">
<div className="info-item"> <div className="info-item">
<span></span> <span><FormattedMessage id="console.response.status"/></span>
<EuiToolTip <EuiToolTip
position="top" position="top"
content={ content={
@ -188,14 +115,16 @@ const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
}`}</EuiText> }`}</EuiText>
} }
> >
<EuiBadge color={mapStatusCodeToBadgeColor(statusCode)}> <EuiText size="s">
{/* Use &nbsp; to ensure that no matter the width we don't allow line breaks */} <EuiBadge color={mapStatusCodeToBadgeColor(statusCode)}>
{statusCode}&nbsp;-&nbsp;{statusText} {/* Use &nbsp; to ensure that no matter the width we don't allow line breaks */}
</EuiBadge> {statusCode}&nbsp;-&nbsp;{statusText}
</EuiBadge>
</EuiText>
</EuiToolTip> </EuiToolTip>
</div> </div>
<div className="info-item"> <div className="info-item">
<span></span> <span><FormattedMessage id="console.response.time_elapsed"/></span>
<EuiToolTip <EuiToolTip
position="top" position="top"
content={ content={
@ -212,11 +141,10 @@ const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
</EuiToolTip> </EuiToolTip>
</div> </div>
<div className="info-item"> <div className="info-item">
<EuiText size="s"> {/* <Button type="link" onClick={()=>{setHeaderInfoVisible(true)}}> */}
<Button type="link" onClick={()=>{setHeaderInfoVisible(true)}}> {/* <FormattedMessage id="console.request.headers"/> */}
Headers Headers
</Button> {/* </Button> */}
</EuiText>
</div> </div>
</div> </div>
</> </>
@ -225,8 +153,8 @@ const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
return ( return (
<div className="request-status-bar"> <div className="request-status-bar">
<div className="bar-item">{clusterContent}</div> {left? <div className="bar-item">{clusterContent}</div>:
<div className="bar-item">{content}</div> [<div className="bar-item">{content}</div>,
<Drawer title="Request header info" <Drawer title="Request header info"
style={{zIndex:1004}} style={{zIndex:1004}}
width={520} width={520}
@ -251,7 +179,8 @@ const [headerInfoVisible, setHeaderInfoVisible] = React.useState(false)
</EuiCodeBlock> </EuiCodeBlock>
</Tabs.TabPane> </Tabs.TabPane>
</Tabs> </Tabs>
</Drawer> </Drawer>]
}
</div> </div>
); );

View File

@ -34,7 +34,7 @@
import $ from 'jquery'; import $ from 'jquery';
// @ts-ignore // @ts-ignore
import { stringify } from 'query-string'; import { stringify } from 'query-string';
import {pathPrefix} from '@/services/common'; import {pathPrefix, ESPrefix} from '@/services/common';
interface SendOptions { interface SendOptions {
asSystemRequest?: boolean; asSystemRequest?: boolean;
@ -48,7 +48,7 @@ export function getVersion() {
} }
export function getContentType(body: unknown) { export function getContentType(body: unknown) {
if (!body) return; if (!body) return 'text/plain';
return 'application/json'; return 'application/json';
} }
@ -75,11 +75,12 @@ export function send(
// } // }
// @ts-ignore // @ts-ignore
const options: JQuery.AjaxSettings = { const options: JQuery.AjaxSettings = {
url: `/elasticsearch/${clusterID}/_proxy?` + stringify({ path, method }), url: `${ESPrefix}/${clusterID}/_proxy?` + stringify({ path, method }),
headers: { // headers: {
'infini-xsrf': 'search-center', // 'infini-xsrf': 'search-center',
...(asSystemRequest && { 'infini-request': 'true' }), // 'origin': location.origin,
}, // ...(asSystemRequest && { 'infini-request': 'true' }),
// },
data, data,
contentType: getContentType(data), contentType: getContentType(data),
cache: false, cache: false,

View File

@ -1,4 +1,5 @@
import alert from './en-US/alert'; import alert from './en-US/alert';
import console from './en-US/console';
export default { export default {
'navBar.lang': 'Languages', 'navBar.lang': 'Languages',
@ -152,6 +153,7 @@ export default {
'menu.system.logs.audit': 'AUDIT', 'menu.system.logs.audit': 'AUDIT',
'menu.system.logs.query': 'QUERY', 'menu.system.logs.query': 'QUERY',
'menu.system.logs.slow': 'SLOW', 'menu.system.logs.slow': 'SLOW',
'menu.system.commonCommand': 'COMMON COMMAND',
'menu.form': 'Form', 'menu.form': 'Form',
@ -405,4 +407,5 @@ export default {
'Setting panel shows in development environment only, please manually modify', 'Setting panel shows in development environment only, please manually modify',
...alert, ...alert,
...console,
}; };

View File

@ -0,0 +1,9 @@
export default {
'console.cluster.status': 'Health',
'console.cluster.endpoint': 'Endpoint',
'console.cluster.version': 'Version',
'console.response.status': 'Response status',
'console.response.time_elapsed': 'Time elapsed',
'console.request.headers': 'Headers',
'console.request.headers.title': 'Request header info',
}

View File

@ -1,4 +1,5 @@
import alert from './zh-CN/alert'; import alert from './zh-CN/alert';
import console from './zh-CN/console';
export default { export default {
'navBar.lang': '语言', 'navBar.lang': '语言',
@ -158,6 +159,7 @@ export default {
'menu.system.logs.audit': '审计日志', 'menu.system.logs.audit': '审计日志',
'menu.system.logs.query': '查询日志', 'menu.system.logs.query': '查询日志',
'menu.system.logs.slow': '慢日志', 'menu.system.logs.slow': '慢日志',
'menu.system.commonCommand': '常用命令',
'menu.form': '表单页', 'menu.form': '表单页',
@ -406,4 +408,5 @@ export default {
'配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件', '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件',
...alert, ...alert,
...console,
}; };

View File

@ -0,0 +1,9 @@
export default {
'console.cluster.status': '健康状态',
'console.cluster.endpoint': '集群地址',
'console.cluster.version': '版本',
'console.response.status': '响应状态',
'console.response.time_elapsed': '时延',
'console.request.headers': '请求头',
'console.request.headers.title': '请求头信息',
}

View File

@ -7,6 +7,7 @@ import {ScopedHistory} from '../../components/kibana/core/public/application/sco
import {notification} from 'antd'; import {notification} from 'antd';
import {connect} from 'dva' import {connect} from 'dva'
import PageHeaderWrapper from '@/components/PageHeaderWrapper'; import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import {ESPrefix} from '@/services/common'
const httpClient = new Fetch({ const httpClient = new Fetch({
basePath:{ basePath:{
@ -41,7 +42,7 @@ const AlertingUI = (props)=>{
} }
useMemo(()=>{ useMemo(()=>{
httpClient.params.basePath.prepend = (url)=>{ httpClient.params.basePath.prepend = (url)=>{
return '/elasticsearch/'+ props.selectedCluster.id +"/" + url; return `${ESPrefix}/${props.selectedCluster.id}/${url}`;
} }
}, [props.selectedCluster]); }, [props.selectedCluster]);
const isDarkMode = false; const isDarkMode = false;

View File

@ -19,6 +19,7 @@ const NewOverview = ()=>{
onChange={()=>{}} onChange={()=>{}}
type="card" type="card"
tabBarGutter={10} tabBarGutter={10}
tabindex="-1"
> >
{panes.map(pane => ( {panes.map(pane => (
<TabPane tab={pane.title} key={pane.key}> <TabPane tab={pane.title} key={pane.key}>

View File

@ -9,6 +9,7 @@
&.left{ &.left{
border-right: 1px solid rgb(232, 232, 232); border-right: 1px solid rgb(232, 232, 232);
padding-right: 15px; padding-right: 15px;
min-width: 642px;
.card-cnt{ .card-cnt{
margin-top: 10px; margin-top: 10px;
.ant-list-item{ .ant-list-item{

View File

@ -9,6 +9,7 @@
&.checked{ &.checked{
background: #1890ff; background: #1890ff;
color: #fff; color: #fff;
border-color: #1890ff;
} }
>.wrapper{ >.wrapper{
font-size: 12px; font-size: 12px;

View File

@ -49,7 +49,8 @@ import {generateFilters} from '../../components/kibana/data/public/query/filter_
import Table from '../../components/kibana/discover/public/application/components/discover_table/table'; import Table from '../../components/kibana/discover/public/application/components/discover_table/table';
import {useQueryParam, StringParam, QueryParamProvider, ArrayParam} from 'use-query-params'; import {useQueryParam, StringParam, QueryParamProvider, ArrayParam} from 'use-query-params';
import {Route} from 'umi' import {Route} from 'umi';
import {ESPrefix} from '@/services/common';
const SidebarMemoized = React.memo(DiscoverSidebar); const SidebarMemoized = React.memo(DiscoverSidebar);
@ -550,7 +551,7 @@ const DiscoverUI = (props)=>{
useMemo(()=>{ useMemo(()=>{
const {http} = getContext(); const {http} = getContext();
http.getServerBasePath = ()=>{ http.getServerBasePath = ()=>{
return '/elasticsearch/'+ props.selectedCluster.id; return `${ESPrefix}/`+ props.selectedCluster.id;
} }
}, [props.selectedCluster]) }, [props.selectedCluster])
useEffect(()=>{ useEffect(()=>{

View File

@ -15,6 +15,7 @@ import styles from '../System/Cluster/step.less';
import clusterBg from '@/assets/cluster_bg.png'; import clusterBg from '@/assets/cluster_bg.png';
import { connect } from 'dva'; import { connect } from 'dva';
import {ESPrefix} from '@/services/common';
const createContent = ( const createContent = (
@ -42,7 +43,7 @@ const IndexPatterns = (props)=> {
const createComponentKey = useMemo(()=>{ const createComponentKey = useMemo(()=>{
const {http, uiSettings} = useGlobalContext(); const {http, uiSettings} = useGlobalContext();
http.getServerBasePath = ()=>{ http.getServerBasePath = ()=>{
return '/elasticsearch/'+ props.selectedCluster.id; return `${ESPrefix}/`+ props.selectedCluster.id;
} }
return 'CreateIndexPatternWizard_'+Math.random(); return 'CreateIndexPatternWizard_'+Math.random();
},[props.selectedCluster]); },[props.selectedCluster]);

View File

@ -23,6 +23,7 @@ import {
import {FieldFormatsRegistry,} from '../../components/kibana/data/common/field_formats'; import {FieldFormatsRegistry,} from '../../components/kibana/data/common/field_formats';
import {baseFormattersPublic} from '../../components/kibana/data/public/field_formats'; import {baseFormattersPublic} from '../../components/kibana/data/public/field_formats';
import { deserializeFieldFormat } from '../../components/kibana/data/public/field_formats/utils/deserialize'; import { deserializeFieldFormat } from '../../components/kibana/data/public/field_formats/utils/deserialize';
import {ESPrefix} from '@/services/common'
const timeBucketConfig = { const timeBucketConfig = {
'histogram:maxBars': 100, 'histogram:maxBars': 100,
@ -304,7 +305,7 @@ const getSearchParams = (indexPattern, internal, sort) =>{
} }
const fetchESRequest = (params, clusterID) => { const fetchESRequest = (params, clusterID) => {
return fetch(`/elasticsearch/${clusterID}/search/ese`, { return fetch(`${ESPrefix}/${clusterID}/search/ese`, {
headers:{ headers:{
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },

View File

@ -1,6 +1,7 @@
import Console from '../../components/kibana/console/components/Console'; import Console from '../../components/kibana/console/components/Console';
import {connect} from 'dva'; import {connect} from 'dva';
import {Tabs, Button, Icon, Menu, Dropdown} from 'antd'; import {Button, Icon, Menu, Dropdown, Tabs} from 'antd';
// import Tabs from '@/components/infini/tabs';
import {useState, useReducer, useCallback, useEffect, useMemo, useRef, useLayoutEffect} from 'react'; import {useState, useReducer, useCallback, useEffect, useMemo, useRef, useLayoutEffect} from 'react';
import {useLocalStorage} from '@/lib/hooks/storage'; import {useLocalStorage} from '@/lib/hooks/storage';
import {setClusterID} from '../../components/kibana/console/modules/mappings/mappings'; import {setClusterID} from '../../components/kibana/console/modules/mappings/mappings';

View File

@ -1,15 +1,15 @@
import request from '@/utils/request'; import request from '@/utils/request';
//import {pathPrefix} from './common'; import {ESPrefix} from './common';
export async function getAliasList(params){ export async function getAliasList(params){
let url = `/elasticsearch/${params.clusterID}/alias`; let url = `${ESPrefix}/${params.clusterID}/alias`;
return request(url,{ return request(url,{
method: 'GET', method: 'GET',
}); });
} }
export async function doAlias(params){ export async function doAlias(params){
let url = `/elasticsearch/${params.clusterID}/alias`; let url = `${ESPrefix}/${params.clusterID}/alias`;
return request(url,{ return request(url,{
method: 'POST', method: 'POST',
body: params.data, body: params.data,

View File

@ -1,8 +1,8 @@
import request from '@/utils/request'; import request from '@/utils/request';
import {buildQueryArgs, pathPrefix} from './common'; import {buildQueryArgs, ESPrefix} from './common';
export async function getClusterVersion(params) { export async function getClusterVersion(params) {
return request(`/elasticsearch/${params.cluster}/version`, { return request(`${ESPrefix}/${params.cluster}/version`, {
method: 'GET' method: 'GET'
}); });
} }
@ -10,13 +10,13 @@ export async function getClusterVersion(params) {
export async function getClusterMetrics(params) { export async function getClusterMetrics(params) {
let id = params.cluster_id; let id = params.cluster_id;
delete(params['cluster_id']); delete(params['cluster_id']);
return request(`/elasticsearch/${id}/metrics?min=${params.timeRange.min}&max=${params.timeRange.max}`, { return request(`${ESPrefix}/${id}/metrics?min=${params.timeRange.min}&max=${params.timeRange.max}`, {
method: 'GET' method: 'GET'
}); });
} }
export async function createClusterConfig(params) { export async function createClusterConfig(params) {
return request(`/elasticsearch/`, { return request(`${ESPrefix}/`, {
method: 'POST', method: 'POST',
body: params, body: params,
}); });
@ -25,21 +25,21 @@ export async function createClusterConfig(params) {
export async function updateClusterConfig(params) { export async function updateClusterConfig(params) {
let id = params.id; let id = params.id;
delete(params['id']); delete(params['id']);
return request(`/elasticsearch/${id}`, { return request(`${ESPrefix}/${id}`, {
method: 'PUT', method: 'PUT',
body: params, body: params,
}); });
} }
export async function deleteClusterConfig(params) { export async function deleteClusterConfig(params) {
return request(`/elasticsearch/${params.id}`, { return request(`${ESPrefix}/${params.id}`, {
method: 'DELETE', method: 'DELETE',
body: params, body: params,
}); });
} }
export async function searchClusterConfig(params) { export async function searchClusterConfig(params) {
let url = `/elasticsearch/_search`; let url = `${ESPrefix}/_search`;
let args = buildQueryArgs({ let args = buildQueryArgs({
name: params.name, name: params.name,
enabled: params.enabled, enabled: params.enabled,
@ -55,14 +55,14 @@ export async function searchClusterConfig(params) {
} }
export async function getClusterStatus(params) { export async function getClusterStatus(params) {
let url = `/elasticsearch/status`; let url = `${ESPrefix}/status`;
return request(url, { return request(url, {
method: 'GET', method: 'GET',
}); });
} }
export async function tryConnect(params) { export async function tryConnect(params) {
let url = `/elasticsearch/try_connect`; let url = `${ESPrefix}/try_connect`;
return request(url, { return request(url, {
method: 'POST', method: 'POST',
body: params, body: params,

View File

@ -1,4 +1,4 @@
export const pathPrefix = '/_search-center'; export const pathPrefix = (API_ENDPOINT || '') + '/_search-center';
export function buildQueryArgs(params){ export function buildQueryArgs(params){
let argsStr = ''; let argsStr = '';
@ -14,4 +14,4 @@ export function buildQueryArgs(params){
return argsStr; return argsStr;
} }
export const ESPrefix = '/elasticsearch'; export const ESPrefix = (API_ENDPOINT || '') + '/elasticsearch';