mirror of
https://github.com/apache/superset.git
synced 2026-04-28 04:25:07 +00:00
@@ -25,15 +25,28 @@ import SaveQuery from 'src/SqlLab/components/SaveQuery';
|
||||
import { initialState, databases } from 'src/SqlLab/fixtures';
|
||||
|
||||
const mockedProps = {
|
||||
queryEditor: {
|
||||
dbId: 1,
|
||||
schema: 'main',
|
||||
sql: 'SELECT * FROM t',
|
||||
},
|
||||
queryEditorId: '123',
|
||||
animation: false,
|
||||
database: databases.result[0],
|
||||
onUpdate: () => {},
|
||||
onSave: () => {},
|
||||
saveQueryWarning: null,
|
||||
columns: [],
|
||||
};
|
||||
|
||||
const mockState = {
|
||||
...initialState,
|
||||
sqlLab: {
|
||||
...initialState.sqlLab,
|
||||
queryEditors: [
|
||||
{
|
||||
id: mockedProps.queryEditorId,
|
||||
dbId: 1,
|
||||
schema: 'main',
|
||||
sql: 'SELECT * FROM t',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const splitSaveBtnProps = {
|
||||
@@ -51,7 +64,7 @@ describe('SavedQuery', () => {
|
||||
it('renders a non-split save button when allows_virtual_table_explore is not enabled', () => {
|
||||
render(<SaveQuery {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
const saveBtn = screen.getByRole('button', { name: /save/i });
|
||||
@@ -62,7 +75,7 @@ describe('SavedQuery', () => {
|
||||
it('renders a save query modal when user clicks save button', () => {
|
||||
render(<SaveQuery {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
const saveBtn = screen.getByRole('button', { name: /save/i });
|
||||
@@ -78,7 +91,7 @@ describe('SavedQuery', () => {
|
||||
it('renders the save query modal UI', () => {
|
||||
render(<SaveQuery {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
const saveBtn = screen.getByRole('button', { name: /save/i });
|
||||
@@ -111,16 +124,18 @@ describe('SavedQuery', () => {
|
||||
});
|
||||
|
||||
it('renders a "save as new" and "update" button if query already exists', () => {
|
||||
const props = {
|
||||
...mockedProps,
|
||||
queryEditor: {
|
||||
...mockedProps.query,
|
||||
remoteId: '42',
|
||||
},
|
||||
};
|
||||
render(<SaveQuery {...props} />, {
|
||||
render(<SaveQuery {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore({
|
||||
...mockState,
|
||||
sqlLab: {
|
||||
...mockState.sqlLab,
|
||||
unsavedQueryEditor: {
|
||||
id: mockedProps.queryEditorId,
|
||||
remoteId: '42',
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const saveBtn = screen.getByRole('button', { name: /save/i });
|
||||
@@ -136,7 +151,7 @@ describe('SavedQuery', () => {
|
||||
it('renders a split save button when allows_virtual_table_explore is enabled', async () => {
|
||||
render(<SaveQuery {...splitSaveBtnProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -151,7 +166,7 @@ describe('SavedQuery', () => {
|
||||
it('renders a save dataset modal when user clicks "save dataset" menu item', async () => {
|
||||
render(<SaveQuery {...splitSaveBtnProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -170,7 +185,7 @@ describe('SavedQuery', () => {
|
||||
it('renders the save dataset modal UI', async () => {
|
||||
render(<SaveQuery {...splitSaveBtnProps} />, {
|
||||
useRedux: true,
|
||||
store: mockStore(initialState),
|
||||
store: mockStore(mockState),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -16,8 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSelector, shallowEqual } from 'react-redux';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { Row, Col } from 'src/components';
|
||||
import { Input, TextArea } from 'src/components/Input';
|
||||
import { t, styled } from '@superset-ui/core';
|
||||
@@ -31,10 +30,11 @@ import {
|
||||
ISaveableDatasource,
|
||||
} from 'src/SqlLab/components/SaveDatasetModal';
|
||||
import { getDatasourceAsSaveableDataset } from 'src/utils/datasourceUtils';
|
||||
import { QueryEditor, SqlLabRootState } from 'src/SqlLab/types';
|
||||
import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
|
||||
import { QueryEditor } from 'src/SqlLab/types';
|
||||
|
||||
interface SaveQueryProps {
|
||||
queryEditor: QueryEditor;
|
||||
queryEditorId: string;
|
||||
columns: ISaveableDatasource['columns'];
|
||||
onSave: (arg0: QueryPayload) => void;
|
||||
onUpdate: (arg0: QueryPayload) => void;
|
||||
@@ -43,30 +43,22 @@ interface SaveQueryProps {
|
||||
}
|
||||
|
||||
type QueryPayload = {
|
||||
autorun: boolean;
|
||||
dbId: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
id?: string;
|
||||
latestQueryId: string;
|
||||
queryLimit: number;
|
||||
remoteId: number;
|
||||
schema: string;
|
||||
schemaOptions: Array<{
|
||||
label: string;
|
||||
title: string;
|
||||
value: string;
|
||||
}>;
|
||||
selectedText: string | null;
|
||||
sql: string;
|
||||
tableOptions: Array<{
|
||||
label: string;
|
||||
schema: string;
|
||||
title: string;
|
||||
type: string;
|
||||
value: string;
|
||||
}>;
|
||||
name: string;
|
||||
};
|
||||
} & Pick<
|
||||
QueryEditor,
|
||||
| 'autorun'
|
||||
| 'dbId'
|
||||
| 'schema'
|
||||
| 'sql'
|
||||
| 'selectedText'
|
||||
| 'remoteId'
|
||||
| 'latestQueryId'
|
||||
| 'queryLimit'
|
||||
| 'tableOptions'
|
||||
| 'schemaOptions'
|
||||
>;
|
||||
|
||||
const Styles = styled.span`
|
||||
span[role='img'] {
|
||||
@@ -81,20 +73,33 @@ const Styles = styled.span`
|
||||
`;
|
||||
|
||||
export default function SaveQuery({
|
||||
queryEditor,
|
||||
queryEditorId,
|
||||
onSave = () => {},
|
||||
onUpdate,
|
||||
saveQueryWarning = null,
|
||||
database,
|
||||
columns,
|
||||
}: SaveQueryProps) {
|
||||
const query = useSelector<SqlLabRootState, QueryEditor>(
|
||||
({ sqlLab: { unsavedQueryEditor } }) => ({
|
||||
const queryEditor = useQueryEditor(queryEditorId, [
|
||||
'autorun',
|
||||
'name',
|
||||
'description',
|
||||
'remoteId',
|
||||
'dbId',
|
||||
'latestQueryId',
|
||||
'queryLimit',
|
||||
'schema',
|
||||
'schemaOptions',
|
||||
'selectedText',
|
||||
'sql',
|
||||
'tableOptions',
|
||||
]);
|
||||
const query = useMemo(
|
||||
() => ({
|
||||
...queryEditor,
|
||||
...(queryEditor.id === unsavedQueryEditor.id && unsavedQueryEditor),
|
||||
columns,
|
||||
}),
|
||||
shallowEqual,
|
||||
[queryEditor, columns],
|
||||
);
|
||||
const defaultLabel = query.name || query.description || t('Undefined');
|
||||
const [description, setDescription] = useState<string>(
|
||||
@@ -114,12 +119,12 @@ export default function SaveQuery({
|
||||
</Menu>
|
||||
);
|
||||
|
||||
const queryPayload = () =>
|
||||
({
|
||||
...query,
|
||||
name: label,
|
||||
description,
|
||||
} as any as QueryPayload);
|
||||
const queryPayload = () => ({
|
||||
...query,
|
||||
name: label,
|
||||
description,
|
||||
dbId: query.dbId ?? 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSaved) setLabel(defaultLabel);
|
||||
|
||||
Reference in New Issue
Block a user