Compare commits

...

10 Commits

Author SHA1 Message Date
Abhi kumar
ca30fad405 Merge branch 'main' into fix/issue-9080 2025-10-30 12:18:48 +05:30
Abhi kumar
2bd9ee3647 Merge branch 'main' into fix/issue-9080 2025-10-29 15:19:09 +05:30
Abhi kumar
d6050cda81 Merge branch 'main' into fix/issue-9080 2025-10-28 12:07:54 +05:30
Abhi kumar
f6c98cad6c Merge branch 'main' into fix/issue-9080 2025-10-27 19:39:20 +05:30
Srikanth Chekuri
ed2d4c84f0 Merge branch 'main' into fix/issue-9080 2025-10-23 16:44:25 +05:30
Abhi kumar
32ae61af6d Merge branch 'main' into fix/issue-9080 2025-10-16 15:55:54 +05:30
Abhi Kumar
fafa13fb52 Merge branch 'main' of https://github.com/SigNoz/signoz into fix/issue-9080 2025-10-14 16:21:52 +05:30
Abhi Kumar
5b9269769d chore: fixed ts issues 2025-10-07 11:49:27 +05:30
Abhi Kumar
af2f36adfa chore: removed non required code 2025-10-07 11:48:19 +05:30
Abhi Kumar
471d15945c fix: added fix for cursor jump issue 2025-10-07 11:41:28 +05:30
6 changed files with 81 additions and 16 deletions

View File

@@ -89,7 +89,7 @@ function QuerySearch({
hardcodedAttributeKeys,
}: {
placeholder?: string;
onChange: (value: string) => void;
onChange: (value: string, syncExpression?: boolean) => void;
queryData: IBuilderQuery;
dataSource: DataSource;
signalSource?: string;
@@ -97,7 +97,7 @@ function QuerySearch({
onRun?: (query: string) => void;
}): JSX.Element {
const isDarkMode = useIsDarkMode();
const [query, setQuery] = useState<string>(queryData.filter?.expression || '');
const [query, setQuery] = useState<string>('');
const [valueSuggestions, setValueSuggestions] = useState<any[]>([]);
const [activeKey, setActiveKey] = useState<string>('');
const [isLoadingSuggestions, setIsLoadingSuggestions] = useState(false);
@@ -108,6 +108,10 @@ function QuerySearch({
errors: [],
});
const [cursorPos, setCursorPos] = useState({ line: 0, ch: 0 });
const [isFocused, setIsFocused] = useState(false);
const [hasInteractedWithQB, setHasInteractedWithQB] = useState(false);
const handleQueryValidation = (newQuery: string): void => {
try {
const validationResponse = validateQuery(newQuery);
@@ -127,13 +131,28 @@ function QuerySearch({
useEffect(() => {
const newQuery = queryData.filter?.expression || '';
// Only mark as external change if the query actually changed from external source
// Only update query from external source when editor is not focused
// When focused, just update the lastExternalQuery to track changes
if (newQuery !== lastExternalQuery) {
setQuery(newQuery);
setIsExternalQueryChange(true);
setLastExternalQuery(newQuery);
}
}, [queryData.filter?.expression, lastExternalQuery]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryData.filter?.expression]);
useEffect(() => {
// Update the query when the editor is blurred and the query has changed
// Only call onChange if the editor has been focused before (not on initial mount)
if (
!isFocused &&
hasInteractedWithQB &&
query !== queryData.filter?.expression
) {
onChange(query, true);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocused]);
// Validate query when it changes externally (from queryData)
useEffect(() => {
@@ -149,9 +168,6 @@ function QuerySearch({
const [showExamples] = useState(false);
const [cursorPos, setCursorPos] = useState({ line: 0, ch: 0 });
const [isFocused, setIsFocused] = useState(false);
const [
isFetchingCompleteValuesList,
setIsFetchingCompleteValuesList,
@@ -1352,8 +1368,13 @@ function QuerySearch({
}}
onFocus={(): void => {
setIsFocused(true);
setHasInteractedWithQB(true);
}}
onBlur={handleBlur}
onCreateEditor={(view: EditorView): EditorView => {
editorRef.current = view;
return view;
}}
/>
{query && validation.isValid === false && !isFocused && (

View File

@@ -34,7 +34,11 @@ export const QueryV2 = memo(function QueryV2({
signalSource = '',
isMultiQueryAllowed = false,
}: QueryProps & { ref: React.RefObject<HTMLDivElement> }): JSX.Element {
const { cloneQuery, panelType } = useQueryBuilder();
const {
cloneQuery,
panelType,
handleSetCurrentFilterExpression,
} = useQueryBuilder();
const showFunctions = query?.functions?.length > 0;
const { dataSource } = query;
@@ -96,12 +100,16 @@ export const QueryV2 = memo(function QueryV2({
);
const handleSearchChange = useCallback(
(value: string) => {
(handleChangeQueryData as HandleChangeQueryDataV5)('filter', {
expression: value,
});
(value: string, syncExpression = false) => {
handleSetCurrentFilterExpression(value, query.queryName);
if (syncExpression) {
(handleChangeQueryData as HandleChangeQueryDataV5)('filter', {
expression: value,
});
}
},
[handleChangeQueryData],
// eslint-disable-next-line react-hooks/exhaustive-deps
[handleSetCurrentFilterExpression, handleChangeQueryData],
);
const handleChangeAggregation = useCallback(

View File

@@ -61,6 +61,8 @@ export const logsQueryRangeSuccessNewFormatResponse = {
};
export const mockQueryBuilderContextValue = {
currentFilterExpression: {},
handleSetCurrentFilterExpression: noop,
isDefaultQuery: (): boolean => false,
currentQuery: {
...initialQueriesMap.logs,

View File

@@ -183,6 +183,8 @@ describe('Logs Explorer Tests', () => {
>
<QueryBuilderContext.Provider
value={{
currentFilterExpression: {},
handleSetCurrentFilterExpression: noop,
isDefaultQuery: (): boolean => false,
currentQuery: {
...initialQueriesMap.metrics,

View File

@@ -65,6 +65,7 @@ import { sanitizeOrderByForExplorer } from 'utils/sanitizeOrderBy';
import { v4 as uuid } from 'uuid';
export const QueryBuilderContext = createContext<QueryBuilderContextType>({
currentFilterExpression: {},
currentQuery: initialQueriesMap.metrics,
supersetQuery: initialQueriesMap.metrics,
lastUsedQuery: null,
@@ -74,6 +75,7 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
initialDataSource: null,
panelType: PANEL_TYPES.TIME_SERIES,
isEnabledQuery: false,
handleSetCurrentFilterExpression: () => {},
handleSetQueryData: () => {},
handleSetTraceOperatorData: () => {},
handleSetFormulaData: () => {},
@@ -133,6 +135,9 @@ export function QueryBuilderProvider({
const [supersetQuery, setSupersetQuery] = useState<QueryState>(queryState);
const [lastUsedQuery, setLastUsedQuery] = useState<number | null>(0);
const [stagedQuery, setStagedQuery] = useState<Query | null>(null);
const [currentFilterExpression, setCurrentFilterExpression] = useState<
Record<string, string | undefined>
>({});
const [queryType, setQueryType] = useState<EQueryType>(queryTypeParam);
@@ -257,6 +262,7 @@ export function QueryBuilderProvider({
setStagedQuery(nextQuery);
setCurrentQuery(newQueryState);
setCurrentFilterExpression({});
setQueryType(type);
},
[prepareQueryBuilderData],
@@ -386,6 +392,16 @@ export function QueryBuilderProvider({
[],
);
const handleSetCurrentFilterExpression = useCallback(
(expression: string, queryName: string) => {
setCurrentFilterExpression((prevState) => ({
...prevState,
[queryName]: expression,
}));
},
[],
);
const removeQueryBuilderEntityByIndex = useCallback(
(type: keyof QueryBuilderData, index: number) => {
setCurrentQuery((prevState) => {
@@ -1027,9 +1043,10 @@ export function QueryBuilderProvider({
filter: {
...item.filter,
expression:
item.filter?.expression.trim() === ''
currentFilterExpression[item.queryName] ??
(item.filter?.expression?.trim() === ''
? ''
: item.filter?.expression ?? '',
: item.filter?.expression ?? ''),
},
filters: {
items: [],
@@ -1053,7 +1070,13 @@ export function QueryBuilderProvider({
},
queryType,
});
}, [currentQuery, location.pathname, queryType, redirectWithQueryBuilderData]);
}, [
currentQuery,
location.pathname,
queryType,
redirectWithQueryBuilderData,
currentFilterExpression,
]);
useEffect(() => {
if (location.pathname !== currentPathnameRef.current) {
@@ -1141,6 +1164,7 @@ export function QueryBuilderProvider({
const contextValues: QueryBuilderContextType = useMemo(
() => ({
currentFilterExpression,
currentQuery: query,
supersetQuery: superQuery,
lastUsedQuery,
@@ -1150,6 +1174,7 @@ export function QueryBuilderProvider({
initialDataSource,
panelType,
isEnabledQuery,
handleSetCurrentFilterExpression,
handleSetQueryData,
handleSetTraceOperatorData,
handleSetFormulaData,
@@ -1175,6 +1200,7 @@ export function QueryBuilderProvider({
isStagedQueryUpdated,
}),
[
currentFilterExpression,
query,
superQuery,
lastUsedQuery,
@@ -1182,6 +1208,7 @@ export function QueryBuilderProvider({
initialDataSource,
panelType,
isEnabledQuery,
handleSetCurrentFilterExpression,
handleSetQueryData,
handleSetTraceOperatorData,
handleSetFormulaData,

View File

@@ -227,6 +227,7 @@ export type QueryBuilderData = {
};
export type QueryBuilderContextType = {
currentFilterExpression: Record<string, string | undefined>;
currentQuery: Query;
stagedQuery: Query | null;
lastUsedQuery: number | null;
@@ -241,6 +242,10 @@ export type QueryBuilderContextType = {
index: number,
traceOperatorData: IBuilderTraceOperator,
) => void;
handleSetCurrentFilterExpression: (
expression: string,
queryName: string,
) => void;
handleSetFormulaData: (index: number, formulaData: IBuilderFormula) => void;
handleSetQueryItemData: (
index: number,