mirror of https://github.com/buster-so/buster.git
fix secondary mount of sql editor
This commit is contained in:
parent
76f479f739
commit
2115c4de06
|
@ -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 }> }) {
|
export default async function ResultsPage({ params }: { params: Promise<{ metricId: string }> }) {
|
||||||
const { metricId } = await params;
|
const { metricId } = await params;
|
||||||
|
|
||||||
return <MetricViewResults metricId={metricId} />;
|
return <MetricViewResultsController metricId={metricId} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }> }) {
|
export default async function ResultsPage({ params }: { params: Promise<{ metricId: string }> }) {
|
||||||
const { metricId } = await params;
|
const { metricId } = await params;
|
||||||
|
|
||||||
return <MetricViewResults metricId={metricId} />;
|
return <MetricViewResultsController metricId={metricId} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { AppSplitter, type AppSplitterRef } from '@/components/ui/layouts/AppSpl
|
||||||
import { SQLContainer } from './SQLContainer';
|
import { SQLContainer } from './SQLContainer';
|
||||||
import { DataContainer } from './DataContainer';
|
import { DataContainer } from './DataContainer';
|
||||||
import type { IDataResult } from '@/api/asset_interfaces';
|
import type { IDataResult } from '@/api/asset_interfaces';
|
||||||
|
import { useMount } from '@/hooks';
|
||||||
|
|
||||||
export interface AppVerticalCodeSplitterProps {
|
export interface AppVerticalCodeSplitterProps {
|
||||||
sql: string;
|
sql: string;
|
||||||
|
|
|
@ -91,9 +91,11 @@ export const AppSplitter = React.memo(
|
||||||
}, [hasHidden, leftHidden, sizes]);
|
}, [hasHidden, leftHidden, sizes]);
|
||||||
|
|
||||||
const memoizedLeftPaneStyle = useMemo(() => {
|
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 {
|
return {
|
||||||
display: isHidden ? 'none' : undefined
|
display: isHidden ? 'none' : undefined,
|
||||||
|
overflow: isEffectivelyHidden ? 'hidden' : undefined
|
||||||
};
|
};
|
||||||
}, [leftHidden, _sizes[0]]);
|
}, [leftHidden, _sizes[0]]);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { BusterChart } from '@/components/ui/charts';
|
||||||
import { cn } from '@/lib/classMerge';
|
import { cn } from '@/lib/classMerge';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { METRIC_CHART_CONTAINER_ID } from './config';
|
import { METRIC_CHART_CONTAINER_ID } from './config';
|
||||||
import { useMount } from '@/hooks';
|
|
||||||
|
|
||||||
interface MetricViewChartContentProps {
|
interface MetricViewChartContentProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
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 { IDataResult } from '@/api/asset_interfaces';
|
||||||
import { useMetricResultsLayout } from './useMetricResultsLayout';
|
import { useMetricResultsLayout } from './useMetricResultsLayout';
|
||||||
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout/ChatLayoutContext';
|
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout/ChatLayoutContext';
|
||||||
|
@ -12,111 +12,109 @@ import { useGetMetric, useGetMetricData } from '@/api/buster_rest/metrics';
|
||||||
|
|
||||||
const autoSaveId = 'metric-view-results';
|
const autoSaveId = 'metric-view-results';
|
||||||
|
|
||||||
export const MetricViewResults: React.FC<{ metricId: string }> = React.memo(({ metricId }) => {
|
export const MetricViewResultsController: React.FC<{ metricId: string }> = React.memo(
|
||||||
const appSplitterRef = React.useRef<AppSplitterRef>(null);
|
({ metricId }) => {
|
||||||
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
const appSplitterRef = React.useRef<AppSplitterRef>(null);
|
||||||
(x) => x.selectedFileViewSecondary
|
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
||||||
);
|
(x) => x.selectedFileViewSecondary
|
||||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
);
|
||||||
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
runSQL,
|
runSQL,
|
||||||
resetRunSQLData,
|
resetRunSQLData,
|
||||||
saveSQL,
|
saveSQL,
|
||||||
saveMetricError,
|
saveMetricError,
|
||||||
runSQLError,
|
runSQLError,
|
||||||
isSavingMetric,
|
isSavingMetric,
|
||||||
isRunningSQL
|
isRunningSQL
|
||||||
} = useMetricRunSQL();
|
} = useMetricRunSQL();
|
||||||
|
|
||||||
const { data: metric } = useGetMetric(
|
const { data: metric } = useGetMetric(
|
||||||
{ id: metricId },
|
{ id: metricId },
|
||||||
{
|
{
|
||||||
select: ({ sql, data_source_id }) => ({
|
select: ({ sql, data_source_id }) => ({
|
||||||
sql,
|
sql,
|
||||||
data_source_id
|
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`]);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
);
|
||||||
//
|
const { data: metricData, isFetched: isFetchedInitialData } = useGetMetricData(
|
||||||
}
|
{ id: metricId },
|
||||||
});
|
{ enabled: false }
|
||||||
|
);
|
||||||
|
|
||||||
const onSaveSQL = useMemoizedFn(async () => {
|
const [sql, setSQL] = useState(metric?.sql || '');
|
||||||
await saveSQL({
|
|
||||||
metricId,
|
const dataSourceId = metric?.data_source_id || '';
|
||||||
sql,
|
const data: IDataResult = metricData?.dataFromRerun || metricData?.data || null;
|
||||||
dataSourceId
|
|
||||||
|
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({
|
const onSaveSQL = useMemoizedFn(async () => {
|
||||||
selectedFileViewSecondary,
|
await saveSQL({
|
||||||
appSplitterRef,
|
metricId,
|
||||||
autoSaveId
|
sql,
|
||||||
});
|
dataSourceId
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
const { defaultLayout, renderSecondary } = useMetricResultsLayout({
|
||||||
if (metric?.sql) {
|
selectedFileViewSecondary,
|
||||||
setSQL(metric.sql);
|
appSplitterRef,
|
||||||
}
|
autoSaveId
|
||||||
}, [metric?.sql]);
|
});
|
||||||
|
|
||||||
useUnmount(() => {
|
useEffect(() => {
|
||||||
resetRunSQLData({ metricId });
|
if (metric?.sql) {
|
||||||
});
|
setSQL(metric.sql);
|
||||||
|
}
|
||||||
|
}, [metric?.sql]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="h-full w-full p-5">
|
<div ref={containerRef} className="h-full w-full p-5">
|
||||||
<AppVerticalCodeSplitter
|
<AppVerticalCodeSplitter
|
||||||
ref={appSplitterRef}
|
ref={appSplitterRef}
|
||||||
autoSaveId={autoSaveId}
|
autoSaveId={autoSaveId}
|
||||||
sql={sql}
|
sql={sql}
|
||||||
setSQL={setSQL}
|
setSQL={setSQL}
|
||||||
runSQLError={runSQLError || saveMetricError}
|
runSQLError={runSQLError || saveMetricError}
|
||||||
topHidden={!renderSecondary}
|
topHidden={!renderSecondary}
|
||||||
onRunQuery={onRunQuery}
|
onRunQuery={onRunQuery}
|
||||||
onSaveSQL={onSaveSQL}
|
onSaveSQL={onSaveSQL}
|
||||||
data={data}
|
data={data}
|
||||||
disabledSave={disableSave}
|
disabledSave={disableSave}
|
||||||
fetchingData={isRunningSQL || isSavingMetric || !isFetchedInitialData}
|
fetchingData={isRunningSQL || isSavingMetric || !isFetchedInitialData}
|
||||||
defaultLayout={defaultLayout}
|
defaultLayout={defaultLayout}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
MetricViewResults.displayName = 'MetricViewResults';
|
MetricViewResultsController.displayName = 'MetricViewResultsController';
|
||||||
|
|
|
@ -120,7 +120,7 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
||||||
(x) => x.selectedFileViewSecondary
|
(x) => x.selectedFileViewSecondary
|
||||||
);
|
);
|
||||||
const onSetFileView = useChatLayoutContextSelector((x) => x.onSetFileView);
|
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
||||||
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
||||||
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
const editableSecondaryView: MetricFileViewSecondary = 'sql-edit';
|
const editableSecondaryView: MetricFileViewSecondary = 'sql-edit';
|
||||||
|
@ -148,14 +148,21 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
// onSetFileView({ secondaryView, fileView: 'results' });
|
// onSetFileView({ secondaryView, fileView: 'results' });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
console.log('href', href);
|
const onClickButton = useMemoizedFn(() => {
|
||||||
|
onChangePage(href, { shallow: true });
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={href}>
|
<Link
|
||||||
|
href={href}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}}>
|
||||||
<SelectableButton
|
<SelectableButton
|
||||||
tooltipText="SQL editor"
|
tooltipText="SQL editor"
|
||||||
icon={<SquareCode />}
|
icon={<SquareCode />}
|
||||||
onClick={() => {}}
|
onClick={onClickButton}
|
||||||
selected={isSelectedView}
|
selected={isSelectedView}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -17,17 +17,13 @@ const VersionHistoryPanel = dynamic(
|
||||||
),
|
),
|
||||||
{ loading }
|
{ loading }
|
||||||
);
|
);
|
||||||
const MetricViewResults = dynamic(
|
|
||||||
() => import('@/controllers/MetricController/MetricViewResults').then((x) => x.MetricViewResults),
|
|
||||||
{ loading }
|
|
||||||
);
|
|
||||||
|
|
||||||
export const MetricSecondaryRecord: Record<
|
export const MetricSecondaryRecord: Record<
|
||||||
MetricFileViewSecondary,
|
MetricFileViewSecondary,
|
||||||
React.FC<FileContainerSecondaryProps>
|
React.FC<FileContainerSecondaryProps>
|
||||||
> = {
|
> = {
|
||||||
'chart-edit': ({ selectedFile }) => <MetricEditController metricId={selectedFile?.id || ''} />,
|
'chart-edit': ({ selectedFile }) => <MetricEditController metricId={selectedFile?.id || ''} />,
|
||||||
'sql-edit': ({ selectedFile }) => <MetricViewResults metricId={selectedFile?.id || ''} />,
|
'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 }) => (
|
'version-history': ({ selectedFile }) => (
|
||||||
<VersionHistoryPanel assetId={selectedFile?.id || ''} type="metric" />
|
<VersionHistoryPanel assetId={selectedFile?.id || ''} type="metric" />
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue