mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
* feat: added traceoperator component and styles * chore: minor style improvments * feat: added conditions for traceoperator * chore: minor UI fixes * chore: type changes * chore: added initialvalue for trace operators * chore: Added changes to prepare request payload * chore: fixed minor styles + minor ux fix * feat: added span selector * chore: added ui changes in the editor * chore: removed traceoperations and reused queryoperations * chore: minor changes in queryaddon and aggregation for support * chore: added traceoperators in alerts * chore: minor pr review change * chore: linter fix * fix: fixed minor ts issues * fix: added limit support in traceoperator * chore: minor fix in traceoperator styles * chore: linting fix + icon changes * chore: updated type * chore: lint fixes * feat: added changes for showing querynames in alerts * feat: added trace operator grammer + antlr files * feat: added traceoperator context util * chore: added traceoperator validation function * feat: added traceoperator editor * feat: added queryname boost + operator constants * fix: pr reviews * chore: minor ui fix * fix: updated grammer files * test: added test for traceoperatorcontext * chore: removed check for multiple queries in traceexplorer * test: minor test fix * test: fixed breaking mapQueryDataFromApi test * chore: fixed logic to show trace operator * chore: updated docs link * chore: minor ui issue fix * chore: changed trace operator query name * chore: removed using spans from in trace opeartors * fix: added fix for order by in trace opeartor * feat: added changes related to saved in views in trace opeartor * chore: added changes to keep indirect descendent operator at bottom * chore: removed returnspansfrom field from traceoperator * chore: updated file names + regenerated grammer * chore: added beta tag in trace opeartor * chore: pr review fixes * Fix/tsc trace operator + tests (#8942) * fix: added tsc fixes for trace operator * chore: moved traceoperator utils * test: added test for traceopertor util * chore: tsc fix * fix: fixed tsc issue * Feat/trace operator dashboards (#8992) * chore: added callout message for multiple queries without trace operators * feat: added changes for supporting trace operators in dashboards * chore: minor changes for list panel
241 lines
6.2 KiB
TypeScript
241 lines
6.2 KiB
TypeScript
import './QuerySection.styles.scss';
|
|
|
|
import { Color } from '@signozhq/design-tokens';
|
|
import { Button, Tabs, Tooltip } from 'antd';
|
|
import logEvent from 'api/common/logEvent';
|
|
import PromQLIcon from 'assets/Dashboard/PromQl';
|
|
import { QueryBuilderV2 } from 'components/QueryBuilderV2/QueryBuilderV2';
|
|
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
|
|
import { ENTITY_VERSION_V4 } from 'constants/app';
|
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
|
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
|
|
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
|
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
|
import { isEmpty } from 'lodash-es';
|
|
import { Atom, Play, Terminal } from 'lucide-react';
|
|
import { useEffect, useMemo, useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
|
import { AlertDef } from 'types/api/alerts/def';
|
|
import { EQueryType } from 'types/common/dashboard';
|
|
|
|
import ChQuerySection from './ChQuerySection';
|
|
import PromqlSection from './PromqlSection';
|
|
import { FormContainer, StepHeading } from './styles';
|
|
|
|
function QuerySection({
|
|
queryCategory,
|
|
setQueryCategory,
|
|
alertType,
|
|
runQuery,
|
|
alertDef,
|
|
panelType,
|
|
ruleId,
|
|
}: QuerySectionProps): JSX.Element {
|
|
// init namespace for translations
|
|
const { t } = useTranslation('alerts');
|
|
const [currentTab, setCurrentTab] = useState(queryCategory);
|
|
|
|
const handleQueryCategoryChange = (queryType: string): void => {
|
|
setQueryCategory(queryType as EQueryType);
|
|
setCurrentTab(queryType as EQueryType);
|
|
};
|
|
|
|
const renderPromqlUI = (): JSX.Element => <PromqlSection />;
|
|
|
|
const renderChQueryUI = (): JSX.Element => <ChQuerySection />;
|
|
|
|
const isDarkMode = useIsDarkMode();
|
|
|
|
const renderMetricUI = (): JSX.Element => (
|
|
<QueryBuilderV2
|
|
panelType={panelType}
|
|
config={{
|
|
queryVariant: 'static',
|
|
initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType],
|
|
}}
|
|
showTraceOperator={alertType === AlertTypes.TRACES_BASED_ALERT}
|
|
showFunctions={
|
|
(alertType === AlertTypes.METRICS_BASED_ALERT &&
|
|
alertDef.version === ENTITY_VERSION_V4) ||
|
|
alertType === AlertTypes.LOGS_BASED_ALERT
|
|
}
|
|
version={alertDef.version || 'v3'}
|
|
/>
|
|
);
|
|
|
|
const tabs = [
|
|
{
|
|
label: (
|
|
<Tooltip title="Query Builder">
|
|
<Button className="nav-btns">
|
|
<Atom size={14} />
|
|
</Button>
|
|
</Tooltip>
|
|
),
|
|
key: EQueryType.QUERY_BUILDER,
|
|
},
|
|
{
|
|
label: (
|
|
<Tooltip title="ClickHouse">
|
|
<Button className="nav-btns">
|
|
<Terminal size={14} />
|
|
</Button>
|
|
</Tooltip>
|
|
),
|
|
key: EQueryType.CLICKHOUSE,
|
|
},
|
|
];
|
|
|
|
const items = useMemo(
|
|
() => [
|
|
{
|
|
label: (
|
|
<Tooltip title="Query Builder">
|
|
<Button className="nav-btns" data-testid="query-builder-tab">
|
|
<Atom size={14} />
|
|
</Button>
|
|
</Tooltip>
|
|
),
|
|
key: EQueryType.QUERY_BUILDER,
|
|
},
|
|
{
|
|
label: (
|
|
<Tooltip title="ClickHouse">
|
|
<Button className="nav-btns">
|
|
<Terminal size={14} />
|
|
</Button>
|
|
</Tooltip>
|
|
),
|
|
key: EQueryType.CLICKHOUSE,
|
|
},
|
|
{
|
|
label: (
|
|
<Tooltip title="PromQL">
|
|
<Button className="nav-btns">
|
|
<PromQLIcon
|
|
fillColor={isDarkMode ? Color.BG_VANILLA_200 : Color.BG_INK_300}
|
|
/>
|
|
</Button>
|
|
</Tooltip>
|
|
),
|
|
key: EQueryType.PROM,
|
|
},
|
|
],
|
|
[isDarkMode],
|
|
);
|
|
|
|
const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
|
|
|
|
useEffect(() => {
|
|
registerShortcut(QBShortcuts.StageAndRunQuery, runQuery);
|
|
|
|
return (): void => {
|
|
deregisterShortcut(QBShortcuts.StageAndRunQuery);
|
|
};
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [runQuery]);
|
|
|
|
const renderTabs = (typ: AlertTypes): JSX.Element | null => {
|
|
switch (typ) {
|
|
case AlertTypes.TRACES_BASED_ALERT:
|
|
case AlertTypes.LOGS_BASED_ALERT:
|
|
case AlertTypes.EXCEPTIONS_BASED_ALERT:
|
|
return (
|
|
<div className="alert-tabs">
|
|
<Tabs
|
|
type="card"
|
|
style={{ width: '100%', padding: '0px 8px' }}
|
|
defaultActiveKey={currentTab}
|
|
activeKey={currentTab}
|
|
onChange={handleQueryCategoryChange}
|
|
tabBarExtraContent={
|
|
<span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
|
<Button
|
|
type="primary"
|
|
onClick={(): void => {
|
|
runQuery();
|
|
logEvent('Alert: Stage and run query', {
|
|
dataSource: ALERTS_DATA_SOURCE_MAP[alertType],
|
|
isNewRule: !ruleId || isEmpty(ruleId),
|
|
ruleId,
|
|
queryType: queryCategory,
|
|
});
|
|
}}
|
|
className="stage-run-query"
|
|
icon={<Play size={14} />}
|
|
>
|
|
Stage & Run Query
|
|
</Button>
|
|
</span>
|
|
}
|
|
items={tabs}
|
|
/>
|
|
</div>
|
|
);
|
|
case AlertTypes.METRICS_BASED_ALERT:
|
|
default:
|
|
return (
|
|
<div className="alert-tabs">
|
|
<Tabs
|
|
type="card"
|
|
style={{ width: '100%', padding: '0px 8px' }}
|
|
defaultActiveKey={currentTab}
|
|
activeKey={currentTab}
|
|
onChange={handleQueryCategoryChange}
|
|
tabBarExtraContent={
|
|
<span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
|
<Button
|
|
type="primary"
|
|
onClick={runQuery}
|
|
className="stage-run-query"
|
|
icon={<Play size={14} />}
|
|
>
|
|
Stage & Run Query
|
|
</Button>
|
|
</span>
|
|
}
|
|
items={items}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
};
|
|
const renderQuerySection = (c: EQueryType): JSX.Element | null => {
|
|
switch (c) {
|
|
case EQueryType.PROM:
|
|
return renderPromqlUI();
|
|
case EQueryType.CLICKHOUSE:
|
|
return renderChQueryUI();
|
|
case EQueryType.QUERY_BUILDER:
|
|
return renderMetricUI();
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const step2Label = alertDef.alertType === 'METRIC_BASED_ALERT' ? '2' : '1';
|
|
|
|
return (
|
|
<>
|
|
<StepHeading> {t('alert_form_step2', { step: step2Label })}</StepHeading>
|
|
<FormContainer className="alert-query-section-container">
|
|
<div>{renderTabs(alertType)}</div>
|
|
{renderQuerySection(currentTab)}
|
|
</FormContainer>
|
|
</>
|
|
);
|
|
}
|
|
|
|
interface QuerySectionProps {
|
|
queryCategory: EQueryType;
|
|
setQueryCategory: (n: EQueryType) => void;
|
|
alertType: AlertTypes;
|
|
runQuery: VoidFunction;
|
|
alertDef: AlertDef;
|
|
panelType: PANEL_TYPES;
|
|
ruleId: string;
|
|
}
|
|
|
|
export default QuerySection;
|