From 5ca04580ee719f5d422fdd1c25006052afbc43dc Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Mon, 13 Jan 2025 17:52:03 +0800 Subject: [PATCH] Deprecate AIAssistantPanel/SqlSnippet.ts --- .../ui/AIAssistantPanel/Message.tsx | 32 +- .../ui/AIAssistantPanel/SqlSnippet.tsx | 455 ------------------ 2 files changed, 14 insertions(+), 473 deletions(-) delete mode 100644 apps/studio/components/ui/AIAssistantPanel/SqlSnippet.tsx diff --git a/apps/studio/components/ui/AIAssistantPanel/Message.tsx b/apps/studio/components/ui/AIAssistantPanel/Message.tsx index 9325418c7ec..1eb5ed6410e 100644 --- a/apps/studio/components/ui/AIAssistantPanel/Message.tsx +++ b/apps/studio/components/ui/AIAssistantPanel/Message.tsx @@ -7,7 +7,6 @@ import remarkGfm from 'remark-gfm' import { AiIconAnimation, cn, CodeBlock, markdownComponents, WarningIcon } from 'ui' import { QueryBlock } from '../QueryBlock/QueryBlock' import CollapsibleCodeBlock from './CollapsibleCodeBlock' -import { SqlSnippet } from './SqlSnippet' interface MessageProps { role: 'function' | 'system' | 'user' | 'assistant' | 'data' | 'tool' @@ -95,23 +94,20 @@ export const Message = function Message({ hideLineNumbers /> ) : ( -
- - -
+ ) ) : ( { - const formatted = (sql || [''])[0] - const propsMatch = formatted.match(/--\s*props:\s*(\{[^}]+\})/) - const props = propsMatch ? JSON.parse(propsMatch[1]) : {} - const title = props.title || 'SQL Query' - const updatedFormatted = formatted?.replace(/--\s*props:\s*\{[^}]+\}/, '').trim() - - return ( -
- -
- ) -} - -interface ParsedSqlProps { - sql: string - title: string - isLoading?: boolean - readOnly?: boolean - isChart: boolean - runQuery?: boolean - xAxis: string - yAxis: string -} - -export const SqlCard = ({ - sql, - isChart, - runQuery = false, - xAxis, - yAxis, - title, - readOnly = false, - isLoading = false, -}: ParsedSqlProps) => { - const router = useRouter() - const { ref } = useParams() - const queryClient = useQueryClient() - const project = useSelectedProject() - const snapV2 = useSqlEditorV2StateSnapshot() - const { setAiAssistantPanel } = useAppStateSnapshot() - const { newQuery } = useNewQuery() - - const isInSQLEditor = router.pathname.includes('/sql') - const isInNewSnippet = router.pathname.endsWith('/sql') - - const [showCode, setShowCode] = useState(readOnly || !runQuery || !isReadOnlySelect(sql)) - const [showResults, setShowResults] = useState(false) - const [results, setResults] = useState() - const [error, setError] = useState() - const [showWarning, setShowWarning] = useState<'hasWriteOperation' | 'hasUnknownFunctions'>() - - const { mutate: sendEvent } = useSendEventMutation() - - const { mutate: executeSql, isLoading: isExecuting } = useExecuteSqlMutation({ - onSuccess: async (res) => { - // [Joshen] Only do contextual invalidation within a project context - if (!!ref) { - const invalidationKeys = getContextualInvalidationKeys({ ref, pathname: router.pathname }) - await Promise.all(invalidationKeys?.map((x) => queryClient.invalidateQueries(x))) - } - - setShowResults(true) - setResults(res.result) - setShowWarning(undefined) - }, - onError: (error) => { - setError(error) - setResults([]) - setShowWarning(undefined) - }, - }) - - const handleExecute = useCallback(() => { - if (!project?.ref || !sql || readOnly) return - - if (!isReadOnlySelect(sql)) { - const hasUnknownFunctions = containsUnknownFunction(sql) - - setShowCode(true) - setShowWarning(hasUnknownFunctions ? 'hasUnknownFunctions' : 'hasWriteOperation') - return - } - - setError(undefined) - executeSql({ - sql: suffixWithLimit(sql, 100), - projectRef: project?.ref, - connectionString: project?.connectionString, - handleError: (error: any) => { - setError(error) - setResults([]) - return { result: [] } - }, - }) - }, [project?.ref, project?.connectionString, sql, executeSql, readOnly]) - - const handleEditInSQLEditor = () => { - if (isInSQLEditor) { - snapV2.setDiffContent(sql, DiffType.Addition) - } else { - newQuery(sql, title) - } - } - - const [errorHeader, ...errorContent] = - (error?.formattedError?.split('\n') ?? [])?.filter((x: string) => x.length > 0) ?? [] - - useEffect(() => { - if (runQuery && isReadOnlySelect(sql) && !results && !readOnly && !isLoading) { - handleExecute() - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [sql, readOnly, isLoading, runQuery]) - - return ( -
-
- {!!showWarning ? ( - -

- {showWarning === 'hasWriteOperation' - ? 'This query contains write operations.' - : 'This query involves running a function.'}{' '} - Are you sure you want to execute it? -

-

- Make sure you are not accidentally removing something important. -

-
- - -
-
- ) : ( - <> - -

{title}

- - {!readOnly && ( -
- } - onClick={() => setShowCode(!showCode)} - tooltip={{ - content: { side: 'bottom', text: showCode ? 'Hide query' : 'Show query' }, - }} - /> - - {!isInSQLEditor || isInNewSnippet ? ( - } - onClick={() => { - handleEditInSQLEditor() - sendEvent({ - action: TelemetryActions.ASSISTANT_EDIT_IN_SQL_EDITOR_CLICKED, - properties: { - isInSQLEditor, - isInNewSnippet, - }, - }) - }} - tooltip={{ content: { side: 'bottom', text: 'Edit in SQL Editor' } }} - /> - ) : ( - - - } - tooltip={{ content: { side: 'bottom', text: 'Edit in SQL Editor' } }} - /> - - - snapV2.setDiffContent(sql, DiffType.Addition)} - > - Insert code - - snapV2.setDiffContent(sql, DiffType.Modification)} - > - Replace code - - snapV2.setDiffContent(sql, DiffType.NewSnippet)} - > - Create new snippet - - - - )} - - } - loading={isExecuting} - onClick={() => { - handleExecute() - if (isReadOnlySelect(sql)) { - sendEvent({ - action: TelemetryActions.ASSISTANT_SUGGESTION_RUN_QUERY_CLICKED, - properties: { queryType: 'select' }, - }) - } - }} - tooltip={{ - content: { - side: 'bottom', - className: 'max-w-56 text-center', - text: isExecuting ? ( - - ) : ( - 'Run query' - ), - }, - }} - /> -
- )} - - )} -
- - {showCode && ( - code]:m-0 [&>code>span]:text-foreground' - )} - /> - )} - - {/* Results Section */} - {results !== undefined && results.length > 0 && isChart && xAxis && yAxis ? ( -
- - - - - } /> - - - -
- ) : ( -
- {error !== undefined ? ( - -
- {errorContent.length > 0 ? ( -
- {errorContent.map((errorText: string, i: number) => ( -
-                            {errorText}
-                          
- ))} - -
- ) : ( - <> -

{error.error}

- - - )} -
- - } - /> - ) : results !== undefined && results.length > 0 ? ( - <> -
- -
-
-

- {results.length} rows - {results.length >= 100 && ` (Limited to only 100 rows)`} -

-
- - ) : ( - results !== undefined && - results.length === 0 && ( -
-

Success. No rows returned.

-
- ) - )} -
- )} -
- ) -} - -export { SqlSnippetWrapper as SqlSnippet }