mirror of https://github.com/buster-so/buster.git
update sql splitter
This commit is contained in:
parent
366f20577f
commit
87376682cb
|
@ -13,18 +13,35 @@ export interface AppVerticalCodeSplitterProps {
|
|||
sql: string;
|
||||
setSQL: (sql: string) => void;
|
||||
runSQLError: string | undefined;
|
||||
onRunQuery: () => Promise<void>;
|
||||
data: DataResult;
|
||||
fetchingData: boolean;
|
||||
defaultLayout: LayoutSize;
|
||||
initialLayout: LayoutSize | null;
|
||||
autoSaveId: string;
|
||||
topHidden?: boolean;
|
||||
onSaveSQL?: () => Promise<void>;
|
||||
disabledSave?: boolean;
|
||||
gapAmount?: number;
|
||||
className?: string;
|
||||
readOnly?: boolean;
|
||||
saveButton:
|
||||
| false
|
||||
| {
|
||||
label?: string;
|
||||
icon?: React.ReactNode;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
onClick: () => Promise<void>;
|
||||
tooltip?: string;
|
||||
};
|
||||
runButton:
|
||||
| false
|
||||
| {
|
||||
label?: string;
|
||||
suffix?: React.ReactNode;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
onClick: () => Promise<void>;
|
||||
tooltip?: string;
|
||||
};
|
||||
}
|
||||
|
||||
const MIN_LEFT_SIZE = 120;
|
||||
|
@ -37,15 +54,14 @@ export const AppVerticalCodeSplitter = forwardRef<AppSplitterRef, AppVerticalCod
|
|||
sql,
|
||||
setSQL,
|
||||
runSQLError,
|
||||
onRunQuery,
|
||||
onSaveSQL,
|
||||
runButton,
|
||||
saveButton,
|
||||
data,
|
||||
readOnly = false,
|
||||
fetchingData,
|
||||
defaultLayout,
|
||||
initialLayout,
|
||||
autoSaveId,
|
||||
disabledSave = false,
|
||||
topHidden = false,
|
||||
gapAmount = 3,
|
||||
className,
|
||||
|
@ -79,13 +95,12 @@ export const AppVerticalCodeSplitter = forwardRef<AppSplitterRef, AppVerticalCod
|
|||
sql={sql}
|
||||
setDatasetSQL={setSQL}
|
||||
error={runSQLError}
|
||||
onRunQuery={onRunQuery}
|
||||
onSaveSQL={onSaveSQL}
|
||||
disabledSave={disabledSave}
|
||||
runButton={runButton}
|
||||
saveButton={saveButton}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
),
|
||||
[sql, setSQL, runSQLError, onRunQuery, onSaveSQL, disabledSave, readOnly]
|
||||
[sql, setSQL, runSQLError, runButton, saveButton, readOnly]
|
||||
)}
|
||||
rightPanelClassName={dataContainerClassName}
|
||||
rightChildren={useMemo(
|
||||
|
|
|
@ -5,31 +5,19 @@ import { ErrorClosableContainer } from '@/components/ui/error/ErrorClosableConta
|
|||
import { Command, ReturnKey } from '@/components/ui/icons';
|
||||
import { AppCodeEditor } from '@/components/ui/inputs/AppCodeEditor';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import { AppTooltip } from '../../tooltip';
|
||||
import type { AppVerticalCodeSplitterProps } from './AppVerticalCodeSplitter';
|
||||
|
||||
export const SQLContainer: React.FC<{
|
||||
className?: string;
|
||||
sql: string | undefined;
|
||||
setDatasetSQL: (sql: string) => void;
|
||||
onRunQuery: () => Promise<void>;
|
||||
onSaveSQL: AppVerticalCodeSplitterProps['onSaveSQL'];
|
||||
disabledSave?: AppVerticalCodeSplitterProps['disabledSave'];
|
||||
error?: string | null;
|
||||
readOnly?: boolean;
|
||||
saveButton?: AppVerticalCodeSplitterProps['saveButton'];
|
||||
runButton?: AppVerticalCodeSplitterProps['runButton'];
|
||||
}> = React.memo(
|
||||
({
|
||||
disabledSave,
|
||||
className = '',
|
||||
readOnly = false,
|
||||
sql,
|
||||
setDatasetSQL,
|
||||
onRunQuery,
|
||||
onSaveSQL,
|
||||
error,
|
||||
}) => {
|
||||
const [isRunning, setIsRunning] = useState(false);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
({ className = '', saveButton, readOnly = false, sql, setDatasetSQL, runButton, error }) => {
|
||||
const { openInfoMessage } = useBusterNotifications();
|
||||
|
||||
const onCopySQL = () => {
|
||||
|
@ -37,59 +25,40 @@ export const SQLContainer: React.FC<{
|
|||
openInfoMessage('SQL copied to clipboard');
|
||||
};
|
||||
|
||||
const onRunQueryPreflight = useMemoizedFn(async () => {
|
||||
setIsRunning(true);
|
||||
try {
|
||||
await onRunQuery();
|
||||
} catch (error) {
|
||||
// Error handling is done by the parent component
|
||||
console.error('Error running query:', error);
|
||||
} finally {
|
||||
setIsRunning(false);
|
||||
}
|
||||
});
|
||||
|
||||
const onSaveSQLPreflight = useMemoizedFn(async () => {
|
||||
setIsSaving(true);
|
||||
try {
|
||||
await onSaveSQL?.();
|
||||
} catch (error) {
|
||||
// Error handling is done by the parent component
|
||||
console.error('Error saving SQL:', error);
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
});
|
||||
|
||||
const memoizedFooter = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<Button onClick={onCopySQL}>Copy SQL</Button>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{onSaveSQL && !readOnly && (
|
||||
<Button
|
||||
disabled={disabledSave || !sql || isRunning}
|
||||
variant="black"
|
||||
loading={isSaving}
|
||||
onClick={onSaveSQLPreflight}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
{saveButton && !readOnly && (
|
||||
<AppTooltip title={saveButton.tooltip} delayDuration={500}>
|
||||
<Button
|
||||
disabled={saveButton?.disabled || !sql}
|
||||
variant="black"
|
||||
loading={saveButton?.loading}
|
||||
onClick={saveButton?.onClick}
|
||||
prefix={saveButton.icon}
|
||||
>
|
||||
{saveButton.label || 'Save'}
|
||||
</Button>
|
||||
</AppTooltip>
|
||||
)}
|
||||
|
||||
{!readOnly && (
|
||||
{!readOnly && runButton && (
|
||||
<Button
|
||||
variant="default"
|
||||
loading={isRunning}
|
||||
loading={runButton?.loading}
|
||||
disabled={!sql}
|
||||
className="flex items-center space-x-0"
|
||||
onClick={onRunQueryPreflight}
|
||||
onClick={runButton?.onClick}
|
||||
suffix={
|
||||
<div className="flex items-center gap-x-1 text-sm">
|
||||
<Command />
|
||||
<ReturnKey />
|
||||
</div>
|
||||
runButton?.suffix || (
|
||||
<div className="flex items-center gap-x-1 text-sm">
|
||||
<Command />
|
||||
<ReturnKey />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
>
|
||||
Run
|
||||
|
@ -98,7 +67,7 @@ export const SQLContainer: React.FC<{
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
}, [disabledSave, isRunning, sql, isSaving]);
|
||||
}, [saveButton, runButton, sql]);
|
||||
|
||||
return (
|
||||
<FileCard
|
||||
|
@ -110,7 +79,7 @@ export const SQLContainer: React.FC<{
|
|||
className="overflow-hidden border-x-0 border-t-0"
|
||||
value={sql}
|
||||
onChange={setDatasetSQL}
|
||||
onMetaEnter={onRunQueryPreflight}
|
||||
onMetaEnter={runButton ? runButton.onClick : undefined}
|
||||
variant={null}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import type { DataResult } from '@buster/server-shared/metrics';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import type { BusterMetric } from '@/api/asset_interfaces';
|
||||
import { useGetMetric, useGetMetricData } from '@/api/buster_rest/metrics';
|
||||
import type { AppSplitterRef, LayoutSize } from '@/components/ui/layouts/AppSplitter';
|
||||
import { AppVerticalCodeSplitter } from '@/components/ui/layouts/AppVerticalCodeSplitter';
|
||||
import {
|
||||
AppVerticalCodeSplitter,
|
||||
type AppVerticalCodeSplitterProps,
|
||||
} from '@/components/ui/layouts/AppVerticalCodeSplitter';
|
||||
import { useChatIsVersionHistoryMode } from '@/context/Chats/useIsVersionHistoryMode';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import { useMetricResultsLayout } from './useMetricResultsLayout';
|
||||
|
@ -52,7 +55,7 @@ export const MetricViewSQLController: React.FC<{
|
|||
const [sql, setSQL] = useState(metric?.sql || '');
|
||||
|
||||
const isSQLChanged = sql !== metric?.sql;
|
||||
const disableSave = !sql || isRunningSQL || isSQLChanged;
|
||||
const disableSave = !sql || isRunningSQL || !isSQLChanged;
|
||||
const dataSourceId = metric?.data_source_id || '';
|
||||
const data: DataResult | null = metricData?.dataFromRerun || metricData?.data || null;
|
||||
|
||||
|
@ -103,6 +106,25 @@ export const MetricViewSQLController: React.FC<{
|
|||
}
|
||||
}, [metric?.sql]);
|
||||
|
||||
const saveButton: AppVerticalCodeSplitterProps['saveButton'] = useMemo(() => {
|
||||
return {
|
||||
label: 'Save',
|
||||
onClick: onSaveSQL,
|
||||
loading: isSavingMetric,
|
||||
disabled: disableSave,
|
||||
tooltip: disableSave ? 'SQL is not changed' : 'Save SQL',
|
||||
};
|
||||
}, [onSaveSQL, isSavingMetric, disableSave]);
|
||||
|
||||
const runButton: AppVerticalCodeSplitterProps['runButton'] = useMemo(() => {
|
||||
return {
|
||||
label: 'Run',
|
||||
onClick: onRunQuery,
|
||||
loading: isRunningSQL,
|
||||
disabled: false,
|
||||
};
|
||||
}, [onRunQuery, isRunningSQL]);
|
||||
|
||||
useViewSQLBlocker({ sql, originalSql: metric?.sql, enabled: isFetchedMetric, onResetToOriginal });
|
||||
|
||||
return (
|
||||
|
@ -113,15 +135,14 @@ export const MetricViewSQLController: React.FC<{
|
|||
sql={sql}
|
||||
setSQL={setSQL}
|
||||
runSQLError={runSQLError || saveMetricError}
|
||||
onRunQuery={onRunQuery}
|
||||
onSaveSQL={onSaveSQL}
|
||||
data={data || []}
|
||||
readOnly={isVersionHistoryMode}
|
||||
disabledSave={disableSave}
|
||||
fetchingData={isRunningSQL || isSavingMetric || !isFetchedInitialData}
|
||||
defaultLayout={defaultLayout}
|
||||
topHidden={false}
|
||||
initialLayout={initialLayout}
|
||||
saveButton={saveButton}
|
||||
runButton={runButton}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue