({
latestQueryFormData: {
@@ -90,15 +90,15 @@ fetchMock.post(
},
);
-test('Shoud render a button', () => {
+test('Should render a button', () => {
const props = createProps();
- render(, { useRedux: true });
+ render(, { useRedux: true });
expect(screen.getByRole('button')).toBeInTheDocument();
});
-test('Shoud open a menu', () => {
+test('Should open a menu', () => {
const props = createProps();
- render(, {
+ render(, {
useRedux: true,
});
@@ -122,9 +122,9 @@ test('Shoud open a menu', () => {
).toBeInTheDocument();
});
-test('Shoud call onOpenPropertiesModal when click on "Edit properties"', () => {
+test('Should call onOpenPropertiesModal when click on "Edit properties"', () => {
const props = createProps();
- render(, {
+ render(, {
useRedux: true,
});
expect(props.onOpenInEditor).toBeCalledTimes(0);
@@ -133,10 +133,10 @@ test('Shoud call onOpenPropertiesModal when click on "Edit properties"', () => {
expect(props.onOpenPropertiesModal).toBeCalledTimes(1);
});
-test('Shoud call getChartDataRequest when click on "View query"', async () => {
+test('Should call getChartDataRequest when click on "View query"', async () => {
const props = createProps();
const getChartDataRequest = jest.spyOn(chartAction, 'getChartDataRequest');
- render(, {
+ render(, {
useRedux: true,
});
@@ -150,9 +150,9 @@ test('Shoud call getChartDataRequest when click on "View query"', async () => {
await waitFor(() => expect(getChartDataRequest).toBeCalledTimes(1));
});
-test('Shoud call onOpenInEditor when click on "Run in SQL Lab"', () => {
+test('Should call onOpenInEditor when click on "Run in SQL Lab"', () => {
const props = createProps();
- render(, {
+ render(, {
useRedux: true,
});
@@ -164,10 +164,10 @@ test('Shoud call onOpenInEditor when click on "Run in SQL Lab"', () => {
expect(props.onOpenInEditor).toBeCalledTimes(1);
});
-test('Shoud call downloadAsImage when click on "Download as image"', () => {
+test('Should call downloadAsImage when click on "Download as image"', () => {
const props = createProps();
const spy = jest.spyOn(downloadAsImage, 'default');
- render(, {
+ render(, {
useRedux: true,
});
diff --git a/superset-frontend/src/explore/components/DisplayQueryButton/index.jsx b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/index.jsx
similarity index 51%
rename from superset-frontend/src/explore/components/DisplayQueryButton/index.jsx
rename to superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/index.jsx
index 56f74d6e3a..dc936a5169 100644
--- a/superset-frontend/src/explore/components/DisplayQueryButton/index.jsx
+++ b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/index.jsx
@@ -16,31 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { useState } from 'react';
+import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import PropTypes from 'prop-types';
-import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
-import htmlSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/htmlbars';
-import markdownSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/markdown';
-import sqlSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql';
-import jsonSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/json';
-import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
-import { styled, t } from '@superset-ui/core';
+import { t } from '@superset-ui/core';
import { Dropdown, Menu } from 'src/common/components';
-import { getClientErrorObject } from 'src/utils/getClientErrorObject';
-import CopyToClipboard from 'src/components/CopyToClipboard';
-import { getChartDataRequest } from 'src/chart/chartAction';
import downloadAsImage from 'src/utils/downloadAsImage';
-import Loading from 'src/components/Loading';
import ModalTrigger from 'src/components/ModalTrigger';
import { sliceUpdated } from 'src/explore/actions/exploreActions';
-import { CopyButton } from 'src/explore/components/DataTableControl';
-
-SyntaxHighlighter.registerLanguage('markdown', markdownSyntax);
-SyntaxHighlighter.registerLanguage('html', htmlSyntax);
-SyntaxHighlighter.registerLanguage('sql', sqlSyntax);
-SyntaxHighlighter.registerLanguage('json', jsonSyntax);
+import ViewQueryModal from '../controls/ViewQueryModal';
const propTypes = {
onOpenPropertiesModal: PropTypes.func,
@@ -54,53 +39,12 @@ const MENU_KEYS = {
EDIT_PROPERTIES: 'edit_properties',
RUN_IN_SQL_LAB: 'run_in_sql_lab',
DOWNLOAD_AS_IMAGE: 'download_as_image',
+ VIEW_QUERY: 'view_query',
};
-const CopyButtonViewQuery = styled(CopyButton)`
- && {
- margin: 0 0 ${({ theme }) => theme.gridUnit}px;
- }
-`;
-
-export const DisplayQueryButton = props => {
+const ExploreAdditionalActionsMenu = props => {
const { datasource } = props.latestQueryFormData;
-
- const [language, setLanguage] = useState(null);
- const [query, setQuery] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
- const [sqlSupported] = useState(
- datasource && datasource.split('__')[1] === 'table',
- );
-
- const beforeOpen = resultType => {
- setIsLoading(true);
-
- getChartDataRequest({
- formData: props.latestQueryFormData,
- resultFormat: 'json',
- resultType,
- })
- .then(response => {
- // Only displaying the first query is currently supported
- const result = response.result[0];
- setLanguage(result.language);
- setQuery(result.query);
- setIsLoading(false);
- setError(null);
- })
- .catch(response => {
- getClientErrorObject(response).then(
- ({ error, message, statusText }) => {
- setError(
- error || message || statusText || t('Sorry, An error occurred'),
- );
- setIsLoading(false);
- },
- );
- });
- };
-
+ const sqlSupported = datasource && datasource.split('__')[1] === 'table';
const handleMenuClick = ({ key, domEvent }) => {
const { slice, onOpenInEditor, latestQueryFormData } = props;
switch (key) {
@@ -124,34 +68,6 @@ export const DisplayQueryButton = props => {
}
};
- const renderQueryModalBody = () => {
- if (isLoading) {
- return ;
- }
- if (error) {
- return {error}
;
- }
- if (query) {
- return (
-
-
-
-
- }
- />
-
- {query}
-
-
- );
- }
- return null;
- };
-
const { slice } = props;
return (
{
{t('Edit properties')}
)}
-
+
{t('View query')}
}
modalTitle={t('View query')}
- beforeOpen={() => beforeOpen('query')}
- modalBody={renderQueryModalBody()}
+ modalBody={
+
+ }
responsive
/>
@@ -198,10 +117,10 @@ export const DisplayQueryButton = props => {
);
};
-DisplayQueryButton.propTypes = propTypes;
+ExploreAdditionalActionsMenu.propTypes = propTypes;
function mapDispatchToProps(dispatch) {
return bindActionCreators({ sliceUpdated }, dispatch);
}
-export default connect(null, mapDispatchToProps)(DisplayQueryButton);
+export default connect(null, mapDispatchToProps)(ExploreAdditionalActionsMenu);
diff --git a/superset-frontend/src/explore/components/controls/ViewQueryModal.tsx b/superset-frontend/src/explore/components/controls/ViewQueryModal.tsx
new file mode 100644
index 0000000000..1234613b50
--- /dev/null
+++ b/superset-frontend/src/explore/components/controls/ViewQueryModal.tsx
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React, { useEffect, useState } from 'react';
+import { styled, t } from '@superset-ui/core';
+import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
+import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
+import CopyToClipboard from 'src/components/CopyToClipboard';
+import Loading from 'src/components/Loading';
+import { CopyButton } from 'src/explore/components/DataTableControl';
+import { getClientErrorObject } from 'src/utils/getClientErrorObject';
+import { getChartDataRequest } from 'src/chart/chartAction';
+import markdownSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/markdown';
+import htmlSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/htmlbars';
+import sqlSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql';
+import jsonSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/json';
+
+const CopyButtonViewQuery = styled(CopyButton)`
+ && {
+ margin: 0 0 ${({ theme }) => theme.gridUnit}px;
+ }
+`;
+
+SyntaxHighlighter.registerLanguage('markdown', markdownSyntax);
+SyntaxHighlighter.registerLanguage('html', htmlSyntax);
+SyntaxHighlighter.registerLanguage('sql', sqlSyntax);
+SyntaxHighlighter.registerLanguage('json', jsonSyntax);
+
+interface Props {
+ latestQueryFormData: object;
+}
+
+const ViewQueryModal: React.FC = props => {
+ const [language, setLanguage] = useState(null);
+ const [query, setQuery] = useState(null);
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const loadChartData = (resultType: string) => {
+ setIsLoading(true);
+ getChartDataRequest({
+ formData: props.latestQueryFormData,
+ resultFormat: 'json',
+ resultType,
+ })
+ .then(response => {
+ // Only displaying the first query is currently supported
+ const result = response.result[0];
+ setLanguage(result.language);
+ setQuery(result.query);
+ setIsLoading(false);
+ setError(null);
+ })
+ .catch(response => {
+ getClientErrorObject(response).then(({ error, message }) => {
+ setError(
+ error ||
+ message ||
+ response.statusText ||
+ t('Sorry, An error occurred'),
+ );
+ setIsLoading(false);
+ });
+ });
+ };
+ useEffect(() => {
+ loadChartData('query');
+ }, [props.latestQueryFormData]);
+
+ if (isLoading) {
+ return ;
+ }
+ if (error) {
+ return {error}
;
+ }
+ if (query) {
+ return (
+
+
+
+
+ }
+ />
+
+ {query}
+
+
+ );
+ }
+ return null;
+};
+
+export default ViewQueryModal;