mirror of https://github.com/apache/superset.git
feat(sqllab): SQLEditor Extension (#24205)
This commit is contained in:
parent
a4d5d7c6b9
commit
1d9a761de5
|
@ -104,6 +104,20 @@ export interface DatabaseConnectionExtension {
|
||||||
onDelete?: (db: any) => void;
|
onDelete?: (db: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for extensions SQL Form.
|
||||||
|
* These will be passed from the SQLEditor
|
||||||
|
*
|
||||||
|
* @param queryEditorId the queryEditor's id
|
||||||
|
* @param setQueryEditorAndSaveSqlWithDebounce Debounced function that saves a query into the query editor
|
||||||
|
* @param startQuery Callback that starts a query from the query editor
|
||||||
|
*/
|
||||||
|
export interface SQLFormExtensionProps {
|
||||||
|
queryEditorId: string;
|
||||||
|
setQueryEditorAndSaveSqlWithDebounce: (sql: string) => void;
|
||||||
|
startQuery: (ctasArg?: any, ctas_method?: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export type Extensions = Partial<{
|
export type Extensions = Partial<{
|
||||||
'alertsreports.header.icon': React.ComponentType;
|
'alertsreports.header.icon': React.ComponentType;
|
||||||
'embedded.documentation.configuration_details': React.ComponentType<ConfigDetailsProps>;
|
'embedded.documentation.configuration_details': React.ComponentType<ConfigDetailsProps>;
|
||||||
|
@ -122,4 +136,5 @@ export type Extensions = Partial<{
|
||||||
/* Custom components to show in the database and dataset delete modals */
|
/* Custom components to show in the database and dataset delete modals */
|
||||||
'database.delete.related': React.ComponentType<DatabaseDeleteRelatedExtensionProps>;
|
'database.delete.related': React.ComponentType<DatabaseDeleteRelatedExtensionProps>;
|
||||||
'dataset.delete.related': React.ComponentType<DatasetDeleteRelatedExtensionProps>;
|
'dataset.delete.related': React.ComponentType<DatasetDeleteRelatedExtensionProps>;
|
||||||
|
'sqleditor.extension.form': React.ComponentType<SQLFormExtensionProps>;
|
||||||
}>;
|
}>;
|
||||||
|
|
|
@ -31,6 +31,8 @@ import {
|
||||||
} from 'src/SqlLab/fixtures';
|
} from 'src/SqlLab/fixtures';
|
||||||
import SqlEditorLeftBar from 'src/SqlLab/components/SqlEditorLeftBar';
|
import SqlEditorLeftBar from 'src/SqlLab/components/SqlEditorLeftBar';
|
||||||
import { api } from 'src/hooks/apiResources/queryApi';
|
import { api } from 'src/hooks/apiResources/queryApi';
|
||||||
|
import { getExtensionsRegistry } from '@superset-ui/core';
|
||||||
|
import setupExtensions from 'src/setup/setupExtensions';
|
||||||
|
|
||||||
jest.mock('src/components/AsyncAceEditor', () => ({
|
jest.mock('src/components/AsyncAceEditor', () => ({
|
||||||
...jest.requireActual('src/components/AsyncAceEditor'),
|
...jest.requireActual('src/components/AsyncAceEditor'),
|
||||||
|
@ -246,4 +248,18 @@ describe('SqlEditor', () => {
|
||||||
fireEvent.click(await findByText('LIMIT:'));
|
fireEvent.click(await findByText('LIMIT:'));
|
||||||
expect(await findByText('10 000')).toBeInTheDocument();
|
expect(await findByText('10 000')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders an Extension if provided', async () => {
|
||||||
|
const extensionsRegistry = getExtensionsRegistry();
|
||||||
|
|
||||||
|
extensionsRegistry.set('sqleditor.extension.form', () => (
|
||||||
|
<>sqleditor.extension.form extension component</>
|
||||||
|
));
|
||||||
|
|
||||||
|
setupExtensions();
|
||||||
|
const { findByText } = setup(mockedProps, store);
|
||||||
|
expect(
|
||||||
|
await findByText('sqleditor.extension.form extension component'),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,7 +30,14 @@ import { CSSTransition } from 'react-transition-group';
|
||||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Split from 'react-split';
|
import Split from 'react-split';
|
||||||
import { css, FeatureFlag, styled, t, useTheme } from '@superset-ui/core';
|
import {
|
||||||
|
css,
|
||||||
|
FeatureFlag,
|
||||||
|
styled,
|
||||||
|
t,
|
||||||
|
useTheme,
|
||||||
|
getExtensionsRegistry,
|
||||||
|
} from '@superset-ui/core';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
import Modal from 'src/components/Modal';
|
import Modal from 'src/components/Modal';
|
||||||
|
@ -205,6 +212,8 @@ const propTypes = {
|
||||||
scheduleQueryWarning: PropTypes.string,
|
scheduleQueryWarning: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const extensionsRegistry = getExtensionsRegistry();
|
||||||
|
|
||||||
const SqlEditor = ({
|
const SqlEditor = ({
|
||||||
tables,
|
tables,
|
||||||
queryEditor,
|
queryEditor,
|
||||||
|
@ -253,6 +262,8 @@ const SqlEditor = ({
|
||||||
const sqlEditorRef = useRef(null);
|
const sqlEditorRef = useRef(null);
|
||||||
const northPaneRef = useRef(null);
|
const northPaneRef = useRef(null);
|
||||||
|
|
||||||
|
const SqlFormExtension = extensionsRegistry.get('sqleditor.extension.form');
|
||||||
|
|
||||||
const startQuery = useCallback(
|
const startQuery = useCallback(
|
||||||
(ctasArg = false, ctas_method = CtasEnum.TABLE) => {
|
(ctasArg = false, ctas_method = CtasEnum.TABLE) => {
|
||||||
if (!database) {
|
if (!database) {
|
||||||
|
@ -673,6 +684,15 @@ const SqlEditor = ({
|
||||||
onDragEnd={onResizeEnd}
|
onDragEnd={onResizeEnd}
|
||||||
>
|
>
|
||||||
<div ref={northPaneRef} className="north-pane">
|
<div ref={northPaneRef} className="north-pane">
|
||||||
|
{SqlFormExtension && (
|
||||||
|
<SqlFormExtension
|
||||||
|
queryEditorId={queryEditor.id}
|
||||||
|
setQueryEditorAndSaveSqlWithDebounce={
|
||||||
|
setQueryEditorAndSaveSqlWithDebounce
|
||||||
|
}
|
||||||
|
startQuery={startQuery}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<AceEditorWrapper
|
<AceEditorWrapper
|
||||||
autocomplete={autocompleteEnabled}
|
autocomplete={autocompleteEnabled}
|
||||||
onBlur={setQueryEditorAndSaveSql}
|
onBlur={setQueryEditorAndSaveSql}
|
||||||
|
|
Loading…
Reference in New Issue