buster/web/src/controllers/MetricController/MetricViewResults/MetricViewResultsController...

104 lines
3.2 KiB
TypeScript
Raw Normal View History

2025-02-06 03:54:06 +08:00
import React, { useEffect, useMemo } from 'react';
2025-02-06 02:27:53 +08:00
import type { MetricViewProps } from '../config';
2025-02-16 12:51:46 +08:00
import { useMetricIndividual } from '@/context/Metrics';
2025-02-20 10:53:49 +08:00
import { AppVerticalCodeSplitter } from '@/components/ui/layout/AppVerticalCodeSplitter';
2025-02-06 03:54:06 +08:00
import { useMemoizedFn, useUnmount } from 'ahooks';
2025-02-06 02:27:53 +08:00
import { IDataResult } from '@/api/asset_interfaces';
import { useMetricLayout } from '../useMetricLayout';
2025-02-20 11:05:30 +08:00
import { AppSplitterRef } from '@/components/ui';
2025-02-19 13:31:56 +08:00
import { useChatLayoutContextSelector } from '@chatLayout/ChatLayoutContext';
2025-02-06 03:54:06 +08:00
import { useSQLContextSelector } from '@/context/SQL';
2025-02-06 02:27:53 +08:00
const autoSaveId = 'metric-view-results';
export const MetricViewResults: React.FC<MetricViewProps> = React.memo(({ metricId }) => {
const appSplitterRef = React.useRef<AppSplitterRef>(null);
const selectedFileViewSecondary = useChatLayoutContextSelector(
(x) => x.selectedFileViewSecondary
);
2025-02-06 03:54:06 +08:00
const containerRef = React.useRef<HTMLDivElement>(null);
const runSQL = useSQLContextSelector((x) => x.runSQL);
const resetRunSQLData = useSQLContextSelector((x) => x.resetRunSQLData);
const saveSQL = useSQLContextSelector((x) => x.saveSQL);
2025-02-06 02:27:53 +08:00
2025-02-16 12:51:46 +08:00
const { metric, metricData } = useMetricIndividual({ metricId });
2025-02-06 02:27:53 +08:00
2025-02-06 03:54:06 +08:00
const [sql, setSQL] = React.useState(metric.code || '');
const [fetchingData, setFetchingData] = React.useState(false);
const dataSourceId = metric?.data_source_id;
2025-02-14 13:52:07 +08:00
const data: IDataResult = metricData?.dataFromRerun || metricData?.data || null;
2025-02-06 02:27:53 +08:00
2025-02-06 03:54:06 +08:00
const disableSave = useMemo(() => {
return !sql || fetchingData || sql === metric.code;
}, [sql, fetchingData, metric.code]);
2025-02-06 02:27:53 +08:00
const onRunQuery = useMemoizedFn(async () => {
2025-02-06 03:54:06 +08:00
setFetchingData(true);
const res = await runSQL({
dataSourceId,
sql,
metricId
});
if (res) {
if (data && data.length > 0) {
const headerHeight = 50;
const heightOfRow = 36;
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);
appSplitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]);
}
}
setFetchingData(false);
});
const onSaveSQL = useMemoizedFn(async () => {
await saveSQL({
metricId,
sql,
dataSourceId
});
2025-02-06 02:27:53 +08:00
});
const { defaultLayout, renderSecondary } = useMetricLayout({
selectedFileViewSecondary,
appSplitterRef,
autoSaveId,
type: 'sql'
});
2025-02-06 03:54:06 +08:00
useEffect(() => {
if (metric.code) {
setSQL(metric.code);
}
}, [metric.code]);
useUnmount(() => {
resetRunSQLData({ metricId });
});
2025-02-06 02:27:53 +08:00
return (
2025-02-06 03:54:06 +08:00
<div ref={containerRef} className="h-full w-full p-3">
2025-02-06 02:27:53 +08:00
<AppVerticalCodeSplitter
ref={appSplitterRef}
autoSaveId={autoSaveId}
sql={sql}
2025-02-06 03:54:06 +08:00
setSQL={setSQL}
2025-02-06 02:27:53 +08:00
runSQLError={null}
topHidden={!renderSecondary}
onRunQuery={onRunQuery}
2025-02-06 03:54:06 +08:00
onSaveSQL={onSaveSQL}
2025-02-06 02:27:53 +08:00
data={data}
2025-02-06 03:54:06 +08:00
disabledSave={disableSave}
fetchingData={fetchingData}
2025-02-06 02:27:53 +08:00
defaultLayout={defaultLayout}
/>
</div>
);
});
MetricViewResults.displayName = 'MetricViewResults';