From 2115c4de065a6fe35b827cb5445c63f2ca3a533d Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Mon, 21 Apr 2025 11:52:19 -0600 Subject: [PATCH] fix secondary mount of sql editor --- .../metrics/[metricId]/results/page.tsx | 4 +- .../metrics/[metricId]/results/page.tsx | 4 +- .../AppVerticalCodeSplitter.tsx | 1 + .../ui/layouts/AppSplitter/AppSplitter.tsx | 6 +- .../MetricViewChartContent.tsx | 1 - .../MetricViewResultsController.tsx | 196 +++++++++--------- .../MetricContainerHeaderButtons.tsx | 15 +- .../secondaryPanelsConfig/metricPanels.tsx | 6 +- 8 files changed, 118 insertions(+), 115 deletions(-) diff --git a/web/src/app/app/(primary_layout)/(chat_experience)/chats/[chatId]/metrics/[metricId]/results/page.tsx b/web/src/app/app/(primary_layout)/(chat_experience)/chats/[chatId]/metrics/[metricId]/results/page.tsx index 625dbdd32..ff82f83af 100644 --- a/web/src/app/app/(primary_layout)/(chat_experience)/chats/[chatId]/metrics/[metricId]/results/page.tsx +++ b/web/src/app/app/(primary_layout)/(chat_experience)/chats/[chatId]/metrics/[metricId]/results/page.tsx @@ -1,7 +1,7 @@ -import { MetricViewResults } from '@/controllers/MetricController/MetricViewResults'; +import { MetricViewResultsController } from '@/controllers/MetricController/MetricViewResults'; export default async function ResultsPage({ params }: { params: Promise<{ metricId: string }> }) { const { metricId } = await params; - return ; + return ; } diff --git a/web/src/app/app/(primary_layout)/(chat_experience)/metrics/[metricId]/results/page.tsx b/web/src/app/app/(primary_layout)/(chat_experience)/metrics/[metricId]/results/page.tsx index 625dbdd32..ff82f83af 100644 --- a/web/src/app/app/(primary_layout)/(chat_experience)/metrics/[metricId]/results/page.tsx +++ b/web/src/app/app/(primary_layout)/(chat_experience)/metrics/[metricId]/results/page.tsx @@ -1,7 +1,7 @@ -import { MetricViewResults } from '@/controllers/MetricController/MetricViewResults'; +import { MetricViewResultsController } from '@/controllers/MetricController/MetricViewResults'; export default async function ResultsPage({ params }: { params: Promise<{ metricId: string }> }) { const { metricId } = await params; - return ; + return ; } diff --git a/web/src/components/features/layouts/AppVerticalCodeSplitter/AppVerticalCodeSplitter.tsx b/web/src/components/features/layouts/AppVerticalCodeSplitter/AppVerticalCodeSplitter.tsx index fa6f5d1d8..91c4683cb 100644 --- a/web/src/components/features/layouts/AppVerticalCodeSplitter/AppVerticalCodeSplitter.tsx +++ b/web/src/components/features/layouts/AppVerticalCodeSplitter/AppVerticalCodeSplitter.tsx @@ -3,6 +3,7 @@ import { AppSplitter, type AppSplitterRef } from '@/components/ui/layouts/AppSpl import { SQLContainer } from './SQLContainer'; import { DataContainer } from './DataContainer'; import type { IDataResult } from '@/api/asset_interfaces'; +import { useMount } from '@/hooks'; export interface AppVerticalCodeSplitterProps { sql: string; diff --git a/web/src/components/ui/layouts/AppSplitter/AppSplitter.tsx b/web/src/components/ui/layouts/AppSplitter/AppSplitter.tsx index 5658cdf99..b64349188 100644 --- a/web/src/components/ui/layouts/AppSplitter/AppSplitter.tsx +++ b/web/src/components/ui/layouts/AppSplitter/AppSplitter.tsx @@ -91,9 +91,11 @@ export const AppSplitter = React.memo( }, [hasHidden, leftHidden, sizes]); const memoizedLeftPaneStyle = useMemo(() => { - const isHidden = leftHidden || _sizes[0] === '0%'; //leftHidden || _sizes[0] === '0px' || _sizes[0] === 0 || _sizes[0] === '0%'; + const isHidden = leftHidden; + const isEffectivelyHidden = _sizes[0] === '0px' || _sizes[0] === '0%'; return { - display: isHidden ? 'none' : undefined + display: isHidden ? 'none' : undefined, + overflow: isEffectivelyHidden ? 'hidden' : undefined }; }, [leftHidden, _sizes[0]]); diff --git a/web/src/controllers/MetricController/MetricViewChart/MetricViewChartContent.tsx b/web/src/controllers/MetricController/MetricViewChart/MetricViewChartContent.tsx index 5aa6c770c..71580d6c2 100644 --- a/web/src/controllers/MetricController/MetricViewChart/MetricViewChartContent.tsx +++ b/web/src/controllers/MetricController/MetricViewChart/MetricViewChartContent.tsx @@ -4,7 +4,6 @@ import { BusterChart } from '@/components/ui/charts'; import { cn } from '@/lib/classMerge'; import React, { useMemo } from 'react'; import { METRIC_CHART_CONTAINER_ID } from './config'; -import { useMount } from '@/hooks'; interface MetricViewChartContentProps { className?: string; diff --git a/web/src/controllers/MetricController/MetricViewResults/MetricViewResultsController.tsx b/web/src/controllers/MetricController/MetricViewResults/MetricViewResultsController.tsx index 8a5ae7a48..9e2c683ce 100644 --- a/web/src/controllers/MetricController/MetricViewResults/MetricViewResultsController.tsx +++ b/web/src/controllers/MetricController/MetricViewResults/MetricViewResultsController.tsx @@ -1,7 +1,7 @@ 'use client'; import React, { useEffect, useMemo, useState } from 'react'; -import { useMemoizedFn, useUnmount } from '@/hooks'; +import { useMemoizedFn, useMount, useUnmount } from '@/hooks'; import { IDataResult } from '@/api/asset_interfaces'; import { useMetricResultsLayout } from './useMetricResultsLayout'; import { useChatLayoutContextSelector } from '@/layouts/ChatLayout/ChatLayoutContext'; @@ -12,111 +12,109 @@ import { useGetMetric, useGetMetricData } from '@/api/buster_rest/metrics'; const autoSaveId = 'metric-view-results'; -export const MetricViewResults: React.FC<{ metricId: string }> = React.memo(({ metricId }) => { - const appSplitterRef = React.useRef(null); - const selectedFileViewSecondary = useChatLayoutContextSelector( - (x) => x.selectedFileViewSecondary - ); - const containerRef = React.useRef(null); +export const MetricViewResultsController: React.FC<{ metricId: string }> = React.memo( + ({ metricId }) => { + const appSplitterRef = React.useRef(null); + const selectedFileViewSecondary = useChatLayoutContextSelector( + (x) => x.selectedFileViewSecondary + ); + const containerRef = React.useRef(null); - const { - runSQL, - resetRunSQLData, - saveSQL, - saveMetricError, - runSQLError, - isSavingMetric, - isRunningSQL - } = useMetricRunSQL(); + const { + runSQL, + resetRunSQLData, + saveSQL, + saveMetricError, + runSQLError, + isSavingMetric, + isRunningSQL + } = useMetricRunSQL(); - const { data: metric } = useGetMetric( - { id: metricId }, - { - select: ({ sql, data_source_id }) => ({ - sql, - data_source_id - }) - } - ); - const { data: metricData, isFetched: isFetchedInitialData } = useGetMetricData( - { id: metricId }, - { enabled: false } - ); - - const [sql, setSQL] = useState(metric?.sql || ''); - - const dataSourceId = metric?.data_source_id || ''; - const data: IDataResult = metricData?.dataFromRerun || metricData?.data || null; - - const disableSave = useMemo(() => { - return !sql || isRunningSQL || sql === metric?.sql; - }, [sql, isRunningSQL, metric?.sql]); - - const onRunQuery = useMemoizedFn(async () => { - try { - const res = await runSQL({ - dataSourceId, - sql, - metricId - }); - - if (res && res.data && res.data.length > 0) { - const data = res.data; - const headerHeight = 28.1; - const heightOfRow = 28.1; - const heightOfDataContainer = headerHeight + heightOfRow * (data.length || 0); - const containerHeight = containerRef.current?.clientHeight || 0; - const maxHeight = Math.floor(containerHeight * 0.6); - const finalHeight = Math.min(heightOfDataContainer, maxHeight) + 12; - appSplitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]); + const { data: metric } = useGetMetric( + { id: metricId }, + { + select: ({ sql, data_source_id }) => ({ + sql, + data_source_id + }) } - } catch (error) { - // - } - }); + ); + const { data: metricData, isFetched: isFetchedInitialData } = useGetMetricData( + { id: metricId }, + { enabled: false } + ); - const onSaveSQL = useMemoizedFn(async () => { - await saveSQL({ - metricId, - sql, - dataSourceId + const [sql, setSQL] = useState(metric?.sql || ''); + + const dataSourceId = metric?.data_source_id || ''; + const data: IDataResult = metricData?.dataFromRerun || metricData?.data || null; + + const disableSave = useMemo(() => { + return !sql || isRunningSQL || sql === metric?.sql; + }, [sql, isRunningSQL, metric?.sql]); + + const onRunQuery = useMemoizedFn(async () => { + try { + const res = await runSQL({ + dataSourceId, + sql, + metricId + }); + + if (res && res.data && res.data.length > 0) { + const data = res.data; + const headerHeight = 28.1; + const heightOfRow = 28.1; + const heightOfDataContainer = headerHeight + heightOfRow * (data.length || 0); + const containerHeight = containerRef.current?.clientHeight || 0; + const maxHeight = Math.floor(containerHeight * 0.6); + const finalHeight = Math.min(heightOfDataContainer, maxHeight) + 12; + appSplitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]); + } + } catch (error) { + // + } }); - }); - const { defaultLayout, renderSecondary } = useMetricResultsLayout({ - selectedFileViewSecondary, - appSplitterRef, - autoSaveId - }); + const onSaveSQL = useMemoizedFn(async () => { + await saveSQL({ + metricId, + sql, + dataSourceId + }); + }); - useEffect(() => { - if (metric?.sql) { - setSQL(metric.sql); - } - }, [metric?.sql]); + const { defaultLayout, renderSecondary } = useMetricResultsLayout({ + selectedFileViewSecondary, + appSplitterRef, + autoSaveId + }); - useUnmount(() => { - resetRunSQLData({ metricId }); - }); + useEffect(() => { + if (metric?.sql) { + setSQL(metric.sql); + } + }, [metric?.sql]); - return ( -
- -
- ); -}); + return ( +
+ +
+ ); + } +); -MetricViewResults.displayName = 'MetricViewResults'; +MetricViewResultsController.displayName = 'MetricViewResultsController'; diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricContainerHeaderButtons.tsx b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricContainerHeaderButtons.tsx index e009859a3..ea5ab0ecd 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricContainerHeaderButtons.tsx +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricContainerHeaderButtons.tsx @@ -120,7 +120,7 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => { const selectedFileViewSecondary = useChatLayoutContextSelector( (x) => x.selectedFileViewSecondary ); - const onSetFileView = useChatLayoutContextSelector((x) => x.onSetFileView); + const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage); const chatId = useChatIndividualContextSelector((x) => x.chatId); const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber); const editableSecondaryView: MetricFileViewSecondary = 'sql-edit'; @@ -148,14 +148,21 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => { // onSetFileView({ secondaryView, fileView: 'results' }); // }); - console.log('href', href); + const onClickButton = useMemoizedFn(() => { + onChangePage(href, { shallow: true }); + }); return ( - + { + e.preventDefault(); + e.stopPropagation(); + }}> } - onClick={() => {}} + onClick={onClickButton} selected={isSelectedView} /> diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerSecondary/secondaryPanelsConfig/metricPanels.tsx b/web/src/layouts/ChatLayout/FileContainer/FileContainerSecondary/secondaryPanelsConfig/metricPanels.tsx index 78286de22..25d1f058e 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerSecondary/secondaryPanelsConfig/metricPanels.tsx +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerSecondary/secondaryPanelsConfig/metricPanels.tsx @@ -17,17 +17,13 @@ const VersionHistoryPanel = dynamic( ), { loading } ); -const MetricViewResults = dynamic( - () => import('@/controllers/MetricController/MetricViewResults').then((x) => x.MetricViewResults), - { loading } -); export const MetricSecondaryRecord: Record< MetricFileViewSecondary, React.FC > = { 'chart-edit': ({ selectedFile }) => , - 'sql-edit': ({ selectedFile }) => , + 'sql-edit': ({ selectedFile }) => <>, //because this is a vertical splitter, we don't want to render the sql edit view in the secondary view because it is vertical 'version-history': ({ selectedFile }) => ( )