mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-26 05:04:29 +08:00
258 lines
6.5 KiB
TypeScript
258 lines
6.5 KiB
TypeScript
import './QueryBuilder.styles.scss';
|
|
|
|
import { Button, Col, Divider, Row, Tooltip } from 'antd';
|
|
import {
|
|
MAX_FORMULAS,
|
|
MAX_QUERIES,
|
|
OPERATORS,
|
|
PANEL_TYPES,
|
|
} from 'constants/queryBuilder';
|
|
// ** Hooks
|
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|
import { DatabaseZap, Sigma } from 'lucide-react';
|
|
// ** Constants
|
|
import { memo, useEffect, useMemo, useRef } from 'react';
|
|
import { DataSource } from 'types/common/queryBuilder';
|
|
|
|
// ** Components
|
|
import { Formula, Query } from './components';
|
|
// ** Types
|
|
import { QueryBuilderProps } from './QueryBuilder.interfaces';
|
|
|
|
export const QueryBuilder = memo(function QueryBuilder({
|
|
config,
|
|
panelType: newPanelType,
|
|
filterConfigs = {},
|
|
queryComponents,
|
|
isListViewPanel = false,
|
|
}: QueryBuilderProps): JSX.Element {
|
|
const {
|
|
currentQuery,
|
|
addNewBuilderQuery,
|
|
addNewFormula,
|
|
handleSetConfig,
|
|
panelType,
|
|
initialDataSource,
|
|
} = useQueryBuilder();
|
|
|
|
const containerRef = useRef(null);
|
|
|
|
const currentDataSource = useMemo(
|
|
() =>
|
|
(config && config.queryVariant === 'static' && config.initialDataSource) ||
|
|
null,
|
|
[config],
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (currentDataSource !== initialDataSource || newPanelType !== panelType) {
|
|
if (newPanelType === PANEL_TYPES.BAR) {
|
|
handleSetConfig(PANEL_TYPES.BAR, DataSource.METRICS);
|
|
return;
|
|
}
|
|
handleSetConfig(newPanelType, currentDataSource);
|
|
}
|
|
}, [
|
|
handleSetConfig,
|
|
panelType,
|
|
initialDataSource,
|
|
currentDataSource,
|
|
newPanelType,
|
|
]);
|
|
|
|
const isDisabledQueryButton = useMemo(
|
|
() => currentQuery.builder.queryData.length >= MAX_QUERIES,
|
|
[currentQuery],
|
|
);
|
|
|
|
const isDisabledFormulaButton = useMemo(
|
|
() => currentQuery.builder.queryFormulas.length >= MAX_FORMULAS,
|
|
[currentQuery],
|
|
);
|
|
|
|
const isAvailableToDisableQuery = useMemo(
|
|
() =>
|
|
currentQuery.builder.queryData.length > 0 ||
|
|
currentQuery.builder.queryFormulas.length > 0,
|
|
[currentQuery],
|
|
);
|
|
|
|
const handleScrollIntoView = (
|
|
entityType: string,
|
|
entityName: string,
|
|
): void => {
|
|
const selectedEntity = document.getElementById(
|
|
`qb-${entityType}-${entityName}`,
|
|
);
|
|
|
|
if (selectedEntity) {
|
|
selectedEntity.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'start',
|
|
inline: 'nearest',
|
|
});
|
|
}
|
|
};
|
|
|
|
const listViewLogFilterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => {
|
|
const config: QueryBuilderProps['filterConfigs'] = {
|
|
stepInterval: { isHidden: true, isDisabled: true },
|
|
having: { isHidden: true, isDisabled: true },
|
|
filters: {
|
|
customKey: 'body',
|
|
customOp: OPERATORS.CONTAINS,
|
|
},
|
|
};
|
|
|
|
return config;
|
|
}, []);
|
|
|
|
const listViewTracesFilterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => {
|
|
const config: QueryBuilderProps['filterConfigs'] = {
|
|
stepInterval: { isHidden: true, isDisabled: true },
|
|
having: { isHidden: true, isDisabled: true },
|
|
limit: { isHidden: true, isDisabled: true },
|
|
filters: {
|
|
customKey: 'body',
|
|
customOp: OPERATORS.CONTAINS,
|
|
},
|
|
};
|
|
|
|
return config;
|
|
}, []);
|
|
|
|
return (
|
|
<Row
|
|
style={{ width: '100%' }}
|
|
gutter={[0, 20]}
|
|
justify="start"
|
|
className="query-builder-container"
|
|
>
|
|
{!isListViewPanel && (
|
|
<div className="new-query-formula-buttons-container">
|
|
<Button.Group>
|
|
<Tooltip title="Add Query">
|
|
<Button disabled={isDisabledQueryButton} onClick={addNewBuilderQuery}>
|
|
<DatabaseZap size={12} />
|
|
</Button>
|
|
</Tooltip>
|
|
|
|
<Tooltip title="Add Formula">
|
|
<Button disabled={isDisabledFormulaButton} onClick={addNewFormula}>
|
|
<Sigma size={12} />
|
|
</Button>
|
|
</Tooltip>
|
|
</Button.Group>
|
|
</div>
|
|
)}
|
|
|
|
<Col span={23} className="qb-entities-list">
|
|
<Row>
|
|
<Col span={1} className="query-builder-left-col">
|
|
{' '}
|
|
</Col>
|
|
|
|
<Col span={23} className="query-builder">
|
|
<Row
|
|
gutter={[0, 16]}
|
|
className="query-builder-queries-formula-container"
|
|
ref={containerRef}
|
|
>
|
|
{panelType === PANEL_TYPES.LIST && isListViewPanel && (
|
|
<Query
|
|
index={0}
|
|
isAvailableToDisable={isAvailableToDisableQuery}
|
|
queryVariant="dropdown"
|
|
query={currentQuery.builder.queryData[0]}
|
|
filterConfigs={
|
|
currentQuery.builder.queryData[0].dataSource === DataSource.TRACES
|
|
? listViewTracesFilterConfigs
|
|
: listViewLogFilterConfigs
|
|
}
|
|
queryComponents={queryComponents}
|
|
isListViewPanel
|
|
/>
|
|
)}
|
|
{!isListViewPanel &&
|
|
currentQuery.builder.queryData.map((query, index) => (
|
|
<Col
|
|
key={query.queryName}
|
|
span={24}
|
|
className="query"
|
|
id={`qb-query-${query.queryName}`}
|
|
>
|
|
<Query
|
|
index={index}
|
|
isAvailableToDisable={isAvailableToDisableQuery}
|
|
queryVariant={config?.queryVariant || 'dropdown'}
|
|
query={query}
|
|
filterConfigs={filterConfigs}
|
|
queryComponents={queryComponents}
|
|
/>
|
|
</Col>
|
|
))}
|
|
{!isListViewPanel &&
|
|
currentQuery.builder.queryFormulas.map((formula, index) => {
|
|
const isAllMetricDataSource = currentQuery.builder.queryData.every(
|
|
(query) => query.dataSource === DataSource.METRICS,
|
|
);
|
|
|
|
const query =
|
|
currentQuery.builder.queryData[index] ||
|
|
currentQuery.builder.queryData[0];
|
|
|
|
return (
|
|
<Col
|
|
key={formula.queryName}
|
|
span={24}
|
|
className="formula"
|
|
id={`qb-formula-${formula.queryName}`}
|
|
>
|
|
<Formula
|
|
filterConfigs={filterConfigs}
|
|
query={query}
|
|
isAdditionalFilterEnable={isAllMetricDataSource}
|
|
formula={formula}
|
|
index={index}
|
|
/>
|
|
</Col>
|
|
);
|
|
})}
|
|
</Row>
|
|
|
|
<Col span={24} className="divider">
|
|
<Divider />
|
|
</Col>
|
|
</Col>
|
|
</Row>
|
|
</Col>
|
|
|
|
{!isListViewPanel && (
|
|
<Col span={1} className="query-builder-mini-map">
|
|
{currentQuery.builder.queryData.map((query) => (
|
|
<Button
|
|
disabled={isDisabledQueryButton}
|
|
className="query-btn"
|
|
key={query.queryName}
|
|
onClick={(): void => handleScrollIntoView('query', query.queryName)}
|
|
>
|
|
{query.queryName}
|
|
</Button>
|
|
))}
|
|
|
|
{currentQuery.builder.queryFormulas.map((formula) => (
|
|
<Button
|
|
disabled={isDisabledFormulaButton}
|
|
className="formula-btn"
|
|
key={formula.queryName}
|
|
onClick={(): void => handleScrollIntoView('formula', formula.queryName)}
|
|
>
|
|
{formula.queryName}
|
|
</Button>
|
|
))}
|
|
</Col>
|
|
)}
|
|
</Row>
|
|
);
|
|
});
|