feat: enhance query context to support detection of values wrapped in quotes

This commit is contained in:
ahrefabhi 2025-06-26 12:45:31 +05:30 committed by SagarRajput-7
parent 62d8dd929a
commit 85caefa945
4 changed files with 26 additions and 16 deletions

View File

@ -12,11 +12,7 @@ import {
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { Color } from '@signozhq/design-tokens'; import { Color } from '@signozhq/design-tokens';
import { copilot } from '@uiw/codemirror-theme-copilot'; import { copilot } from '@uiw/codemirror-theme-copilot';
import CodeMirror, { import CodeMirror, { EditorView, keymap } from '@uiw/react-codemirror';
EditorView,
keymap,
Extension,
} from '@uiw/react-codemirror';
import { Button, Card, Collapse, Popover, Space, Tag, Typography } from 'antd'; import { Button, Card, Collapse, Popover, Space, Tag, Typography } from 'antd';
import { getKeySuggestions } from 'api/querySuggestions/getKeySuggestions'; import { getKeySuggestions } from 'api/querySuggestions/getKeySuggestions';
import { getValueSuggestions } from 'api/querySuggestions/getValueSuggestion'; import { getValueSuggestions } from 'api/querySuggestions/getValueSuggestion';
@ -62,17 +58,17 @@ const stopEventsExtension = EditorView.domEventHandlers({
}, },
}); });
const disallowMultipleSpaces: Extension = EditorView.inputHandler.of( // const disallowMultipleSpaces: Extension = EditorView.inputHandler.of(
(view, from, to, text) => { // (view, from, to, text) => {
const currentLine = view.state.doc.lineAt(from); // const currentLine = view.state.doc.lineAt(from);
const before = currentLine.text.slice(0, from - currentLine.from); // const before = currentLine.text.slice(0, from - currentLine.from);
const after = currentLine.text.slice(to - currentLine.from); // const after = currentLine.text.slice(to - currentLine.from);
const newText = before + text + after; // const newText = before + text + after;
return /\s{2,}/.test(newText); // return /\s{2,}/.test(newText);
}, // },
); // );
function QuerySearch({ function QuerySearch({
onChange, onChange,
@ -217,7 +213,8 @@ function QuerySearch({
// just wrap in quotes but not brackets (we're already in brackets) // just wrap in quotes but not brackets (we're already in brackets)
if ( if (
(type === 'value' || type === 'keyword') && (type === 'value' || type === 'keyword') &&
!/^[a-zA-Z0-9_][a-zA-Z0-9_.\[\]]*$/.test(value) !/^[a-zA-Z0-9_][a-zA-Z0-9_.\[\]]*$/.test(value) &&
!queryContext?.isValueWrappedInQuotes
) { ) {
return wrapStringValueInQuotes(value); return wrapStringValueInQuotes(value);
} }
@ -949,7 +946,6 @@ function QuerySearch({
javascript({ jsx: false, typescript: false }), javascript({ jsx: false, typescript: false }),
EditorView.lineWrapping, EditorView.lineWrapping,
stopEventsExtension, stopEventsExtension,
disallowMultipleSpaces,
keymap.of([ keymap.of([
...completionKeymap, ...completionKeymap,
{ {

View File

@ -40,6 +40,7 @@ export interface IQueryContext {
isInConjunction?: boolean; isInConjunction?: boolean;
isInParenthesis?: boolean; isInParenthesis?: boolean;
isInBracketList?: boolean; // For multi-value operators like IN where values are in brackets isInBracketList?: boolean; // For multi-value operators like IN where values are in brackets
isValueWrappedInQuotes?: boolean;
keyToken?: string; keyToken?: string;
operatorToken?: string; operatorToken?: string;
valueToken?: string; valueToken?: string;

View File

@ -13,6 +13,7 @@ import {
isNonValueOperatorToken, isNonValueOperatorToken,
isOperatorToken, isOperatorToken,
isValueToken, isValueToken,
isWrappedUnderQuotes,
} from './tokenUtils'; } from './tokenUtils';
// Function to normalize multiple spaces to single spaces when not in quotes // Function to normalize multiple spaces to single spaces when not in quotes
@ -714,6 +715,8 @@ export function getQueryContextAtCursor(
const operatorToken = currentPair?.operator || ''; const operatorToken = currentPair?.operator || '';
const valueToken = currentPair?.value || ''; const valueToken = currentPair?.value || '';
const isValueWrappedInQuotes = isWrappedUnderQuotes(valueToken);
// Determine if we're in a multi-value operator context // Determine if we're in a multi-value operator context
const isForMultiValueOperator = isMultiValueOperator(operatorToken); const isForMultiValueOperator = isMultiValueOperator(operatorToken);
@ -739,6 +742,7 @@ export function getQueryContextAtCursor(
isInFunction: false, isInFunction: false,
isInParenthesis: isInParenthesisBoundary || false, isInParenthesis: isInParenthesisBoundary || false,
isInBracketList: isInBracketListBoundary || false, isInBracketList: isInBracketListBoundary || false,
isValueWrappedInQuotes: isValueWrappedInQuotes,
keyToken: isInKeyBoundary keyToken: isInKeyBoundary
? keyToken ? keyToken
: isInOperatorBoundary || finalIsInValue : isInOperatorBoundary || finalIsInValue

View File

@ -75,3 +75,12 @@ export function isFunctionToken(tokenType: number): boolean {
FilterQueryLexer.HASNONE, FilterQueryLexer.HASNONE,
].includes(tokenType); ].includes(tokenType);
} }
export function isWrappedUnderQuotes(token: string): boolean {
if (!token) return false;
const sanitizedToken = token.trim();
return (
(sanitizedToken.startsWith('"') && sanitizedToken.endsWith('"')) ||
(sanitizedToken.startsWith("'") && sanitizedToken.endsWith("'"))
);
}