console/web/src/pages/DataManagement/Insight/InsightBar/index.tsx

223 lines
5.9 KiB
TypeScript

import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import SaveQueries from "../SaveQueries";
import LoadQueries from "../LoadQueries";
import InsightConfig, { ISearchConfig } from "../InsightConfig";
import styles from './index.less';
import { create, list, remove, update } from "../services/queries";
import FullScreen from "../FullScreen";
import { Icon, message } from "antd";
import SearchInfo from "../SearchInfo";
import Histogram from "../Histogram";
import ViewLayout from "../ViewLayout";
export interface IQueries {
clusterId: string;
indexPattern: any;
query: any;
timeField: string;
timefilter: any;
getFilters: () => any;
getBucketSize: () => string;
columns: string[];
}
export interface IRecord {
id?: string;
title: string;
tags: string[];
description?: string;
author?: string;
updated?: string;
created?: string;
}
export interface IProps {
queries: IQueries;
loading: boolean;
isEmpty: boolean;
mode: string;
onModeChange: (mode: string) => void;
onQueriesSelect: (item: IRecord) => void;
onQueriesRemove: (id: string) => void;
onFullScreen: () => void;
layoutConfig: {
layout: any;
onChange: (layout: any) => void;
},
getVisualizations: () => any[]
searchInfo: any;
selectedQueriesId: string;
searchConfig: ISearchConfig;
onSearchConfigChange: (value: any, name: string) => void;
showLayoutListIcon: boolean;
viewLayout: any;
onViewLayoutChange: (layout: any) => void;
}
export default forwardRef((props: IProps, ref: any) => {
const {
queries,
loading: searchLoading,
isEmpty,
mode,
onModeChange,
onFullScreen,
onQueriesSelect,
onQueriesRemove,
layoutConfig,
getVisualizations,
searchInfo,
selectedQueriesId,
searchConfig,
onSearchConfigChange,
showLayoutListIcon,
viewLayout,
onViewLayoutChange,
histogramProps = {}
} = props;
const {
clusterId,
indexPattern,
query,
timeField,
timefilter,
getFilters,
getBucketSize,
columns
} = queries;
const [record, setRecord] = useState<IRecord>();
const [data, setData] = useState<IRecord[]>([]);
const [tags, setTags] = useState<string[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const onSelect = (item: IRecord) => {
setRecord(item)
onQueriesSelect(item)
};
const onDelete =async (id: string) => {
setLoading(true);
await remove(id);
if (record?.id === id) {
setRecord(undefined)
}
onQueriesRemove(id)
setLoading(false);
fetchList(indexPattern.title, clusterId, 1500)
};
const onSave = async (newRecord: IRecord, callback?: () => void) => {
setLoading(true)
const { id, ...values } = newRecord;
const action = id ? update : create;
const filters = getFilters();
const filter = {} as any;
if (filters) filter.filters = filters;
if (columns) filter.columns = columns;
const body = {
...(id ? newRecord : values),
cluster_id: clusterId,
index_pattern: indexPattern.title,
time_field: timeField,
filter,
query,
time_filter: {
from: timefilter.getTime().from,
to: timefilter.getTime().to,
},
bucket_size: getBucketSize(),
visualizations: getVisualizations()
};
const res = await action(body) as { _id: string, result: string }
setRecord({ id: res._id, ...newRecord })
setLoading(false)
if (callback) callback();
fetchList(indexPattern.title, clusterId, 1500)
}
const fetchList = async (index: string, cluster: string, interval: number = 0) => {
setLoading(true)
setTimeout(async () => {
const res = await list({ index_pattern: index, cluster_id: cluster}) as any;
if (res?.hits?.hits) {
const newData = res.hits.hits.map((item: any) => ({...item._source }));
setData(newData);
setTags(Array.from(new Set(newData.map((item: any) => item.tags || []).flat(Infinity))));
}
setLoading(false)
}, interval)
}
const handleModeChange = (newMode: string) => {
if (newMode === mode) {
return;
}
if (isEmpty) return;
if (!timeField) {
message.warning('Please select a time field')
return;
}
onModeChange(newMode)
}
useImperativeHandle(ref, () => ({
loadQueries: (id: string) => data.find((item) => item.id === id)
}));
useEffect(() => {
if (indexPattern.title && clusterId) {
fetchList(indexPattern.title, clusterId)
}
}, [indexPattern.title, clusterId])
useEffect(() => {
if (selectedQueriesId) {
const sq = data.find((item) => item.id === selectedQueriesId)
if (sq) {
onSelect(sq)
}
}
}, [selectedQueriesId, JSON.stringify(data)]);
return (
<div className={styles.bar}>
<SearchInfo {...searchInfo} loading={searchLoading}/>
{ histogramProps?.histogramData && <Histogram {...histogramProps}/>}
<SaveQueries
tags={tags}
onTagsChange={setTags}
loading={loading}
record={record}
onQueriesSave={onSave}
data={data}
/>
<LoadQueries
tags={tags}
data={data}
loading={loading}
onSelect={onSelect}
onDelete={onDelete}
/>
{ showLayoutListIcon && <ViewLayout layout={viewLayout} indexPattern={indexPattern} clusterId={clusterId} onChange={onViewLayoutChange}/> }
{/* <Icon
type={"pie-chart"}
title={"Auto Insight"}
onClick={() => handleModeChange('insight')}
/> */}
{/* <Icon
type={"table"}
title={"Normal Table"}
onClick={() => handleModeChange("table")}
/> */}
{ !isEmpty && mode !== "table" && <FullScreen onFullScreen={onFullScreen}/> }
<InsightConfig
searchConfig={searchConfig}
onSearchConfigChange={onSearchConfigChange}
layoutConfig={layoutConfig}
/>
</div>
);
})