diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.DatePickers.tsx b/apps/studio/components/interfaces/Settings/Logs/Logs.DatePickers.tsx index c765e41434a..9eb29a5e48b 100644 --- a/apps/studio/components/interfaces/Settings/Logs/Logs.DatePickers.tsx +++ b/apps/studio/components/interfaces/Settings/Logs/Logs.DatePickers.tsx @@ -47,9 +47,8 @@ export const LogsDatePicker = ({ helpers, defaultHelper }: PropsWithChildren { if (selectedHelperId) { diff --git a/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx b/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx index de852f4e4e5..cb3dd1b25ad 100644 --- a/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx +++ b/apps/studio/components/interfaces/Settings/Logs/LogsQueryPanel.tsx @@ -66,7 +66,6 @@ const LogsQueryPanel = ({ onDataSourceChange, }: LogsQueryPanelProps) => { const [showReference, setShowReference] = useState(false) - const { timestampStart, timestampEnd, setTimeRange } = useLogsUrlState() const { projectAuthAll: authEnabled, diff --git a/apps/studio/components/ui/CodeEditor/CodeEditor.tsx b/apps/studio/components/ui/CodeEditor/CodeEditor.tsx index 9b5a8eb2c1a..f511d1fe8a2 100644 --- a/apps/studio/components/ui/CodeEditor/CodeEditor.tsx +++ b/apps/studio/components/ui/CodeEditor/CodeEditor.tsx @@ -229,6 +229,45 @@ const CodeEditor = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [monaco, project, formatDocument.enabled]) + // Update run action when callback changes + useEffect(() => { + if (!editorRef.current || !monacoRef.current || !runQuery.enabled) return + + const editor = editorRef.current + const monaco = monacoRef.current + + // Remove existing action if it exists + const action = editor.getAction('run-query') + + if (action) { + action.run = async () => {} // Clear the run function to prevent any stale callbacks + } + + // Add updated action + editor.addAction({ + id: 'run-query', + label: 'Run Query', + keybindings: [monaco.KeyMod.CtrlCmd + monaco.KeyCode.Enter], + contextMenuGroupId: 'operation', + contextMenuOrder: 0, + run: async () => { + const selection = editor.getSelection() + const model = editor.getModel() + if (!model || !selection) return + + const selectedValue = model.getValueInRange(selection) + runQuery.callback(selectedValue || editor.getValue()) + }, + }) + + return () => { + const action = editor.getAction('run-query') + if (action) { + action.run = async () => {} // Clear the run function to prevent any stale callbacks + } + } + }, [runQuery.callback, runQuery.enabled]) + return ( <> { const editorRef = useRef() const [editorId] = useState(uuidv4()) - const { timestampStart, timestampEnd, setTimeRange } = useLogsUrlState() + const { timestampStart, timestampEnd } = useLogsUrlState() const [editorValue, setEditorValue] = useState(PLACEHOLDER_QUERY) const [warehouseEditorId, setWarehouseEditorId] = useState(uuidv4()) @@ -106,7 +106,6 @@ export const LogsExplorerPage: NextPageWithLayout = () => { logData, error, isLoading: logsLoading, - changeQuery, runQuery, setParams, } = useLogsQuery( @@ -187,56 +186,68 @@ export const LogsExplorerPage: NextPageWithLayout = () => { addRecentLogSqlSnippet({ sql: template.searchString }) } - const handleRun = (value?: string | React.MouseEvent) => { - const query = typeof value === 'string' ? value || editorValue : editorValue + const handleRun = useCallback( + (value?: string) => { + const sql = typeof value === 'string' ? value : editorValue - if (sourceType === 'warehouse') { - const whQuery = warehouseEditorValue + if (!sql) return - if (!warehouseCollections?.length) { - toast.error('You do not have any collections yet.') - return + if (sourceType === 'warehouse') { + const whQuery = warehouseEditorValue + + if (!warehouseCollections?.length) { + toast.error('You do not have any collections yet.') + return + } + + // Check that a collection name is included in the query + const collectionNames = warehouseCollections?.map((collection) => collection.name) + const collectionExists = collectionNames?.find((collectionName) => + whQuery.includes(collectionName) + ) + + if (!collectionExists) { + toast.error('Please specify a collection name in the query') + return + } + + // Check that the user is not trying to query logs tables and warehouse collections at the same time + const logsSources = Object.values(LOGS_TABLES) + const logsSourceExists = logsSources.find((source) => whQuery.includes(source)) + + if (logsSourceExists) { + return toast.error('Cannot query logs tables from current query.') + } + + runWarehouseQuery() + return router.push({ + pathname: router.pathname, + query: { ...router.query, q: sql }, + }) } - // Check that a collection name is included in the query - const collectionNames = warehouseCollections?.map((collection) => collection.name) - const collectionExists = collectionNames?.find((collectionName) => - whQuery.includes(collectionName) - ) - - if (!collectionExists) { - toast.error('Please specify a collection name in the query') - return + const currentParams = { + project: projectRef, + sql, + iso_timestamp_start: timestampStart, + iso_timestamp_end: timestampEnd, } - // Check that the user is not trying to query logs tables and warehouse collections at the same time - const logsSources = Object.values(LOGS_TABLES) - const logsSourceExists = logsSources.find((source) => whQuery.includes(source)) + setParams(currentParams) + runQuery() - if (logsSourceExists) { - return toast.error('Cannot query logs tables from current query.') - } - - runWarehouseQuery() - return router.push({ - pathname: router.pathname, - query: { ...router.query, q: query }, - }) - } - - setParams((prev: typeof params) => ({ - ...prev, - sql: query, - iso_timestamp_start: timestampStart, - iso_timestamp_end: timestampEnd, - })) - runQuery() - router.push({ - pathname: router.pathname, - query: { ...router.query, q: query }, - }) - addRecentLogSqlSnippet({ sql: query }) - } + addRecentLogSqlSnippet({ sql }) + }, + [ + editorValue, + warehouseEditorValue, + sourceType, + warehouseCollections, + projectRef, + timestampStart, + timestampEnd, + ] + ) const handleInsertSource = (source: string) => { if (sourceType === 'warehouse') { @@ -352,13 +363,9 @@ export const LogsExplorerPage: NextPageWithLayout = () => { } }, [timestampStart, organization]) - // Ensure default date range is set in URL state on first load useEffect(() => { - const defaultHelper = getDefaultHelper(EXPLORER_DATEPICKER_HELPERS) - if (!timestampStart && !timestampEnd) { - setTimeRange(defaultHelper.calcFrom(), defaultHelper.calcTo()) - } - }, [timestampStart, timestampEnd, setTimeRange]) + console.log('editorValue', editorValue) + }, [editorValue]) return (
@@ -404,7 +411,9 @@ export const LogsExplorerPage: NextPageWithLayout = () => { editorRef={editorRef} language="pgsql" defaultValue={editorValue} - onInputChange={(v) => setEditorValue(v || '')} + onInputChange={(v) => { + setEditorValue(v || '') + }} actions={{ runQuery: { enabled: true, callback: handleRun } }} /> )}