chore: adjust discover (#151)
* fix: add time range to suggestions's request * fix: adjust DatePicker's display * chore: hide search info automatically in discover * chore: adjust discover's histogram * chore: update release notes --------- Co-authored-by: yaojiping <yaojiping@infini.ltd> Co-authored-by: Hardy <luohoufu@infinilabs.com>
This commit is contained in:
parent
1cd1f98af4
commit
932a2a46e1
|
@ -18,9 +18,11 @@ Information about release notes of INFINI Console is provided here.
|
|||
### Bug fix
|
||||
- Fixed the error when querying empty metric data (#144)
|
||||
- Fixed empty host when setup step finishes (#147)
|
||||
- Fixed the error of obtaining suggestions of field's value in discover
|
||||
|
||||
### Improvements
|
||||
- Update agent config with cluster name (#148)
|
||||
- Optimize UI of histogram and datepicker in discover (#151)
|
||||
- Support viewing logs for cluster, node, index health change events (#150)
|
||||
|
||||
## 1.28.2 (2025-02-15)
|
||||
|
|
|
@ -18,12 +18,13 @@ title: "版本历史"
|
|||
### Bug fix
|
||||
- 修复指标数据为空时的查询错误 (#144)
|
||||
- 修复初始化结束步骤中主机显示为错误的问题 (#147)
|
||||
- 修复数据探索中获取字段值建议的错误
|
||||
|
||||
### Improvements
|
||||
- 优化下发给 Agent 的配置,增加集群名称 (#148)
|
||||
- 优化柱状图和时间选择器的 UI (#151)
|
||||
- 集群,节点,索引健康状态变更支持查看日志 (#150)
|
||||
|
||||
|
||||
## 1.28.2 (2025-02-15)
|
||||
|
||||
### Features
|
||||
|
|
|
@ -215,7 +215,7 @@ const DatePicker = (props) => {
|
|||
isMinimum ? styles.minimum : ""
|
||||
} ${className}`}
|
||||
>
|
||||
<Button.Group className={styles.RangeBox}>
|
||||
<Button.Group className={styles.RangeBox} style={{ width: onRefresh ? 'calc(100% - 64px)' : 'calc(100% - 32px)'}}>
|
||||
{!isMinimum && (
|
||||
<Button
|
||||
className={`${styles.iconBtn} common-ui-datepicker-backward`}
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
align-items: center;
|
||||
margin-left: 4px !important;
|
||||
.play {
|
||||
min-width: 30px;
|
||||
max-width: 30px;
|
||||
min-width: 32px;
|
||||
max-width: 32px;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
color: #1890ff;
|
||||
|
|
|
@ -121,6 +121,9 @@ function FilterBarUI(props: Props) {
|
|||
onCancel={() => setIsAddFilterPopoverOpen(false)}
|
||||
key={JSON.stringify(newFilter)}
|
||||
services={props.services}
|
||||
dateRangeFrom={props.dateRangeFrom}
|
||||
dateRangeTo={props.dateRangeTo}
|
||||
timeField={props.timeField}
|
||||
/>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -313,6 +313,9 @@ class FilterEditorUI extends Component<Props, State> {
|
|||
onChange={this.onParamsChange}
|
||||
data-test-subj="phraseValueInput"
|
||||
services={this.props.services}
|
||||
dateRangeFrom={this.props.dateRangeFrom}
|
||||
dateRangeTo={this.props.dateRangeTo}
|
||||
timeField={this.props.timeField}
|
||||
/>
|
||||
);
|
||||
case 'phrases':
|
||||
|
@ -323,6 +326,9 @@ class FilterEditorUI extends Component<Props, State> {
|
|||
values={this.state.params}
|
||||
onChange={this.onParamsChange}
|
||||
services={this.props.services}
|
||||
dateRangeFrom={this.props.dateRangeFrom}
|
||||
dateRangeTo={this.props.dateRangeTo}
|
||||
timeField={this.props.timeField}
|
||||
/>
|
||||
);
|
||||
case 'range':
|
||||
|
|
|
@ -82,17 +82,30 @@ export class PhraseSuggestorUI<
|
|||
protected updateSuggestions = debounce(async (query: string = "") => {
|
||||
if (this.abortController) this.abortController.abort();
|
||||
this.abortController = new AbortController();
|
||||
const { indexPattern, field } = this.props as PhraseSuggestorProps;
|
||||
const { indexPattern, field, dateRangeFrom, dateRangeTo, timeField } = this.props as PhraseSuggestorProps;
|
||||
if (!field || !this.isSuggestingValues()) {
|
||||
return;
|
||||
}
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
const boolFilter = []
|
||||
if (dateRangeFrom && dateRangeTo && timeField) {
|
||||
boolFilter.push({
|
||||
"range": {
|
||||
[timeField]: {
|
||||
"gte": dateRangeFrom,
|
||||
"lte": dateRangeTo
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const suggestions = await this.props.services.data.autocomplete.getValueSuggestions(
|
||||
{
|
||||
indexPattern,
|
||||
field,
|
||||
query,
|
||||
boolFilter,
|
||||
signal: this.abortController.signal,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -50,8 +50,7 @@ class PhraseValueInputUI extends PhraseSuggestorUI<Props> {
|
|||
}
|
||||
|
||||
private renderWithSuggestions() {
|
||||
let { suggestions } = this.state;
|
||||
suggestions = suggestions || [];
|
||||
const suggestions = Array.isArray(this.state.suggestions) ? this.state.suggestions : []
|
||||
const { value, intl, onChange } = this.props;
|
||||
// there are cases when the value is a number, this would cause an exception
|
||||
const valueAsStr = String(value);
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
@include euiBreakpoint("m", "l", "xl") {
|
||||
.kbnQueryBar__datePickerWrapper {
|
||||
// sass-lint:disable-block no-important
|
||||
max-width: 340px;
|
||||
max-width: 400px;
|
||||
flex-grow: 0 !important;
|
||||
flex-basis: auto !important;
|
||||
margin-right: -$euiSizeXS;
|
||||
|
|
|
@ -264,7 +264,7 @@ export default function QueryBarTopRow(props: QueryBarTopRowProps) {
|
|||
return (
|
||||
<NoDataPopover storage={storage} showNoDataPopover={props.indicateNoData}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="s">
|
||||
{renderHistogram()}
|
||||
{/* {renderHistogram()} */}
|
||||
{renderDatePicker()}
|
||||
<EuiFlexItem grow={false}>{button}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -484,6 +484,9 @@ class SearchBarUI extends Component<SearchBarProps, State> {
|
|||
filters={this.props.filters!}
|
||||
onFiltersUpdated={this.props.onFiltersUpdated}
|
||||
indexPatterns={this.props.indexPatterns!}
|
||||
dateRangeFrom={this.state.dateRangeFrom}
|
||||
dateRangeTo={this.state.dateRangeTo}
|
||||
timeField={this.props.timeSetting?.timeField}
|
||||
services={this.props.services}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1122,7 +1122,7 @@ const Discover = (props) => {
|
|||
getVisualizations={() => visRef?.current?.getVisualizations()}
|
||||
searchInfo={{
|
||||
took,
|
||||
hits,
|
||||
total: hits,
|
||||
...timeChartProps,
|
||||
}}
|
||||
selectedQueriesId={selectedQueriesId}
|
||||
|
@ -1160,6 +1160,10 @@ const Discover = (props) => {
|
|||
}
|
||||
}}
|
||||
showLayoutListIcon={false}
|
||||
histogramProps={{
|
||||
histogramData,
|
||||
timefilterUpdateHandler
|
||||
}}
|
||||
// viewLayout={viewLayout}
|
||||
// onViewLayoutChange={(layout) => {
|
||||
// if (layout) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { DiscoverHistogram } from "@/components/vendor/discover/public/application/components/histogram/histogram";
|
||||
import { Icon, Popover } from "antd"
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import styles from "./index.less";
|
||||
|
||||
export default (props) => {
|
||||
|
||||
const { histogramData, timefilterUpdateHandler } = props
|
||||
|
||||
const [visible, setVisible] = useState(false)
|
||||
|
||||
return (
|
||||
<Popover
|
||||
visible={visible}
|
||||
placement="left"
|
||||
title={null}
|
||||
overlayClassName={styles.histogram}
|
||||
content={(
|
||||
<DiscoverHistogram
|
||||
chartData={histogramData}
|
||||
timefilterUpdateHandler={timefilterUpdateHandler}
|
||||
/>
|
||||
)}>
|
||||
<Icon type="bar-chart" style={{color: '#006BB4', cursor: 'pointer'}} onClick={() => {
|
||||
setVisible(!visible)
|
||||
}}/>
|
||||
</Popover>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
.histogram {
|
||||
z-index: 1;
|
||||
:global {
|
||||
.ant-popover-inner-content {
|
||||
width: 400px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,9 @@ import InsightConfig, { ISearchConfig } from "../InsightConfig";
|
|||
import styles from './index.less';
|
||||
import { create, list, remove, update } from "../services/queries";
|
||||
import FullScreen from "../FullScreen";
|
||||
import ModeHandler from "../ModeHandler";
|
||||
import { Icon, message } from "antd";
|
||||
import SearchInfo from "../SearchInfo";
|
||||
import Histogram from "../Histogram";
|
||||
import ViewLayout from "../ViewLayout";
|
||||
|
||||
export interface IQueries {
|
||||
|
@ -72,7 +72,8 @@ export default forwardRef((props: IProps, ref: any) => {
|
|||
onSearchConfigChange,
|
||||
showLayoutListIcon,
|
||||
viewLayout,
|
||||
onViewLayoutChange
|
||||
onViewLayoutChange,
|
||||
histogramProps = {}
|
||||
} = props;
|
||||
|
||||
const {
|
||||
|
@ -183,6 +184,7 @@ export default forwardRef((props: IProps, ref: any) => {
|
|||
return (
|
||||
<div className={styles.bar}>
|
||||
<SearchInfo {...searchInfo} loading={searchLoading}/>
|
||||
{ histogramProps?.histogramData && <Histogram {...histogramProps}/>}
|
||||
<SaveQueries
|
||||
tags={tags}
|
||||
onTagsChange={setTags}
|
||||
|
|
|
@ -30,7 +30,7 @@ export interface IProps {
|
|||
* selected interval
|
||||
*/
|
||||
stateInterval: string;
|
||||
hits: number;
|
||||
total: number;
|
||||
took?: number;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ export default ({
|
|||
dateFormat,
|
||||
timeRange,
|
||||
stateInterval,
|
||||
hits,
|
||||
total,
|
||||
took,
|
||||
}: IProps) => {
|
||||
const [interval, setInterval] = useState(stateInterval);
|
||||
|
@ -69,7 +69,7 @@ export default ({
|
|||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<div style={{ fontSize: 12}}>
|
||||
Found <span style={{fontWeight: "bold" }}>{hits}</span>{" "}
|
||||
Found <span style={{fontWeight: "bold" }}>{total}</span>{" "}
|
||||
records {took && (
|
||||
<span style={{marginLeft: 5 }}>
|
||||
({took} milliscond)
|
||||
|
|
|
@ -1,17 +1,40 @@
|
|||
import { Icon, Popover } from "antd"
|
||||
import { useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Info, { IProps } from "./Info";
|
||||
import styles from './index.scss';
|
||||
|
||||
export default (props: IProps & { loading: boolean }) => {
|
||||
|
||||
const [showResultCount, setShowResultCount] = useState(true);
|
||||
const { loading, total } = props
|
||||
|
||||
if (typeof props.hits !== 'number' || props.hits <= 0) return null;
|
||||
const [showResultCount, setShowResultCount] = useState(true);
|
||||
const timerRef = useRef(null)
|
||||
const autoHiddenRef = useRef(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
if (showResultCount) {
|
||||
timerRef.current = setTimeout(() => {
|
||||
if (autoHiddenRef.current) {
|
||||
setShowResultCount(false)
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
}, [showResultCount])
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
autoHiddenRef.current = true
|
||||
}
|
||||
}, [loading])
|
||||
|
||||
if (typeof total !== 'number' || total <= 0) return null;
|
||||
|
||||
return (
|
||||
<Popover
|
||||
visible={!props.loading && showResultCount}
|
||||
visible={!loading && showResultCount}
|
||||
placement="left"
|
||||
title={null}
|
||||
overlayClassName={styles.searchInfo}
|
||||
|
@ -21,7 +44,14 @@ export default (props: IProps & { loading: boolean }) => {
|
|||
dateFormat={"YYYY-MM-DD H:mm"}
|
||||
/>
|
||||
)}>
|
||||
<Icon type="info-circle" style={{color: '#006BB4', cursor: 'pointer'}} onClick={() => setShowResultCount(!showResultCount)}/>
|
||||
<Icon type="info-circle" style={{color: '#006BB4', cursor: 'pointer'}} onClick={() => {
|
||||
if (showResultCount) {
|
||||
autoHiddenRef.current = true
|
||||
} else {
|
||||
autoHiddenRef.current = false
|
||||
}
|
||||
setShowResultCount(!showResultCount)
|
||||
}}/>
|
||||
</Popover>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue