Skip to content

Commit

Permalink
Merge branch 'master' into fix/scroll-in-dash-sidepane
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneTorap committed Aug 9, 2022
2 parents df9b318 + e214e1a commit a913b18
Show file tree
Hide file tree
Showing 35 changed files with 1,315 additions and 424 deletions.
21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ updates:
labels:
- npm
- dependabot
versioning-strategy: increase

- package-ecosystem: "pip"
directory: "/requirements/"
Expand All @@ -21,9 +22,29 @@ updates:
schedule:
interval: "daily"
open-pull-requests-limit: 0
versioning-strategy: increase

- package-ecosystem: "npm"
directory: "/docs/"
schedule:
interval: "daily"
open-pull-requests-limit: 0
versioning-strategy: increase

- package-ecosystem: "npm"
directory: "/superset-websocket/"
schedule:
interval: "daily"
labels:
- npm
- dependabot
versioning-strategy: increase

- package-ecosystem: "npm"
directory: "/superset-websocket/utils/client-ws-app/"
schedule:
interval: "daily"
labels:
- npm
- dependabot
versioning-strategy: increase
18 changes: 11 additions & 7 deletions requirements/integration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#
backports-entry-points-selectable==1.1.0
# via virtualenv
build==0.8.0
# via pip-tools
cfgv==3.3.0
# via pre-commit
click==8.0.4
Expand All @@ -24,19 +26,21 @@ identify==2.2.13
nodeenv==1.6.0
# via pre-commit
packaging==21.3
# via tox
# via
# build
# tox
pep517==0.11.0
# via pip-tools
# via build
pip-compile-multi==2.4.1
# via -r integration.in
pip-tools==6.2.0
# via -r requirements/integration.in
pip-tools==6.8.0
# via pip-compile-multi
platformdirs==2.2.0
# via virtualenv
pluggy==0.13.1
# via tox
pre-commit==2.14.0
# via -r integration.in
# via -r requirements/integration.in
py==1.10.0
# via tox
pyparsing==3.0.6
Expand All @@ -52,11 +56,11 @@ toml==0.10.2
# pre-commit
# tox
tomli==1.2.1
# via pep517
# via build
toposort==1.6
# via pip-compile-multi
tox==3.25.1
# via -r integration.in
# via -r requirements/integration.in
virtualenv==20.7.2
# via
# pre-commit
Expand Down
2 changes: 1 addition & 1 deletion requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ rsa==4.7.2
# via google-auth
statsd==3.3.0
# via -r requirements/testing.in
trino==0.313.0
trino==0.315.0
# via apache-superset
typing-inspect==0.7.1
# via libcst
Expand Down
31 changes: 31 additions & 0 deletions superset-frontend/packages/superset-ui-core/src/api/types/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.
*/

// /superset/sqllab_viz
interface SqlLabPostRequest {
data: {
schema: string;
sql: string;
dbId: number;
templateParams?: string | undefined;
datasourceName: string;
metrics?: string[];
columns?: string[];
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type ReturningDisplayable<P = void> = (props: P) => string | React.ReactElement;
export type Extensions = Partial<{
'embedded.documentation.description': ReturningDisplayable;
'embedded.documentation.url': string;
'dashboard.nav.right': React.ComponentType;
'navbar.right': React.ComponentType;
'welcome.banner': React.ComponentType;
}>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ describe('SavedQuery', () => {
const closeBtn = screen.getByRole('button', { name: /close/i });
const saveDatasetHeader = screen.getByText(/save or overwrite dataset/i);
const saveRadio = screen.getByRole('radio', {
name: /save as new untitled dataset/i,
name: /save as new untitled/i,
});
const saveLabel = screen.getByText(/save as new/i);
const saveTextbox = screen.getByRole('textbox');
Expand Down
5 changes: 3 additions & 2 deletions superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ import { Form, FormItem } from 'src/components/Form';
import Modal from 'src/components/Modal';
import SaveDatasetActionButton from 'src/SqlLab/components/SaveDatasetActionButton';
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
import { getDatasourceAsSaveableDataset } from 'src/utils/datasourceUtils';

interface SaveQueryProps {
query: any;
query: QueryPayload;
defaultLabel: string;
onSave: (arg0: QueryPayload) => void;
onUpdate: (arg0: QueryPayload) => void;
Expand Down Expand Up @@ -177,7 +178,7 @@ export default function SaveQuery({
onHide={() => setShowSaveDatasetModal(false)}
buttonTextOnSave={t('Save & Explore')}
buttonTextOnOverwrite={t('Overwrite & Explore')}
datasource={query}
datasource={getDatasourceAsSaveableDataset(query)}
/>
<Modal
className="save-query-modal"
Expand Down
5 changes: 4 additions & 1 deletion superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,10 @@ class SqlEditor extends React.PureComponent {
<div className="rightItems">
<span>
<SaveQuery
query={qe}
query={{
...qe,
columns: this.props.latestQuery?.results?.columns || [],
}}
defaultLabel={qe.name || qe.description}
onSave={this.saveQuery}
onUpdate={this.props.actions.updateSavedQuery}
Expand Down
16 changes: 16 additions & 0 deletions superset-frontend/src/dashboard/components/Header/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import React from 'react';
import { render, screen, fireEvent } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import fetchMock from 'fetch-mock';
import { getExtensionsRegistry } from '@superset-ui/core';
import setupExtensions from 'src/setup/setupExtensions';
import { HeaderProps } from './types';
import Header from '.';

Expand Down Expand Up @@ -327,3 +329,17 @@ test('should refresh the charts', async () => {
userEvent.click(screen.getByText('Refresh dashboard'));
expect(mockedProps.onRefresh).toHaveBeenCalledTimes(1);
});

test('should render an extension component if one is supplied', () => {
const extensionsRegistry = getExtensionsRegistry();
extensionsRegistry.set('dashboard.nav.right', () => (
<>dashboard.nav.right extension component</>
));
setupExtensions();

const mockedProps = createProps();
setup(mockedProps);
expect(
screen.getByText('dashboard.nav.right extension component'),
).toBeInTheDocument();
});
13 changes: 12 additions & 1 deletion superset-frontend/src/dashboard/components/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
import moment from 'moment';
import React from 'react';
import PropTypes from 'prop-types';
import { styled, css, t, getSharedLabelColor } from '@superset-ui/core';
import {
styled,
css,
t,
getSharedLabelColor,
getUiOverrideRegistry,
} from '@superset-ui/core';
import { Global } from '@emotion/react';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import {
Expand Down Expand Up @@ -53,6 +59,8 @@ import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants';
import { PageHeaderWithActions } from 'src/components/PageHeaderWithActions';
import { DashboardEmbedModal } from '../DashboardEmbedControls';

const uiOverrideRegistry = getUiOverrideRegistry();

const propTypes = {
addSuccessToast: PropTypes.func.isRequired,
addDangerToast: PropTypes.func.isRequired,
Expand Down Expand Up @@ -483,6 +491,8 @@ class Header extends React.PureComponent {
dashboardTitleChanged(updates.title);
};

const NavExtension = uiOverrideRegistry.get('dashboard.nav.right');

return (
<div
css={headerContainerStyle}
Expand Down Expand Up @@ -602,6 +612,7 @@ class Header extends React.PureComponent {
/>
) : (
<div css={actionButtonsStyle}>
{NavExtension && <NavExtension />}
{userCanEdit && (
<Button
buttonStyle="secondary"
Expand Down
54 changes: 54 additions & 0 deletions superset-frontend/src/explore/actions/datasourcesActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
* under the License.
*/
import { DatasourceType } from '@superset-ui/core';
import fetchMock from 'fetch-mock';
import {
setDatasource,
changeDatasource,
saveDataset,
} from 'src/explore/actions/datasourcesActions';
import sinon from 'sinon';
import * as ClientError from 'src/utils/getClientErrorObject';
import datasourcesReducer from '../reducers/datasourcesReducer';
import { updateFormDataByDatasource } from './exploreActions';

Expand Down Expand Up @@ -51,10 +55,21 @@ const NEW_DATASOURCE = {
description: null,
};

const SAVE_DATASET_POST_ARGS = {
schema: 'foo',
sql: 'select * from bar',
database: { id: 1 },
templateParams: undefined,
datasourceName: 'new dataset',
columns: [],
};

const defaultDatasourcesReducerState = {
[CURRENT_DATASOURCE.uid]: CURRENT_DATASOURCE,
};

const saveDatasetEndpoint = `glob:*/superset/sqllab_viz/`;

test('sets new datasource', () => {
const newState = datasourcesReducer(
defaultDatasourcesReducerState,
Expand Down Expand Up @@ -83,3 +98,42 @@ test('change datasource action', () => {
updateFormDataByDatasource(CURRENT_DATASOURCE, NEW_DATASOURCE),
);
});

test('saveDataset handles success', async () => {
const datasource = { id: 1 };
const saveDatasetResponse = {
data: datasource,
};
fetchMock.reset();
fetchMock.post(saveDatasetEndpoint, saveDatasetResponse);
const dispatch = sinon.spy();
const getState = sinon.spy(() => ({ explore: { datasource } }));
const dataset = await saveDataset(SAVE_DATASET_POST_ARGS)(dispatch);

expect(fetchMock.calls(saveDatasetEndpoint)).toHaveLength(1);
expect(dispatch.callCount).toBe(1);
const thunk = dispatch.getCall(0).args[0];
thunk(dispatch, getState);
expect(dispatch.getCall(1).args[0].type).toEqual('SET_DATASOURCE');

expect(dataset).toEqual(datasource);
});

test('updateSlice with add to existing dashboard handles failure', async () => {
fetchMock.reset();
const sampleError = new Error('sampleError');
fetchMock.post(saveDatasetEndpoint, { throws: sampleError });
const dispatch = sinon.spy();
const errorSpy = jest.spyOn(ClientError, 'getClientErrorObject');

let caughtError;
try {
await saveDataset(SAVE_DATASET_POST_ARGS)(dispatch);
} catch (error) {
caughtError = error;
}

expect(caughtError).toEqual(sampleError);
expect(fetchMock.calls(saveDatasetEndpoint)).toHaveLength(4);
expect(errorSpy).toHaveBeenCalledWith(sampleError);
});
46 changes: 45 additions & 1 deletion superset-frontend/src/explore/actions/datasourcesActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
* under the License.
*/

import { Dispatch } from 'redux';
import { Dispatch, AnyAction } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { Dataset } from '@superset-ui/chart-controls';
import { SupersetClient } from '@superset-ui/core';
import { addDangerToast } from 'src/components/MessageToasts/actions';
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
import { updateFormDataByDatasource } from './exploreActions';
import { ExplorePageState } from '../types';

Expand All @@ -31,6 +35,45 @@ export function setDatasource(datasource: Dataset) {
return { type: SET_DATASOURCE, datasource };
}

export function saveDataset({
schema,
sql,
database,
templateParams,
datasourceName,
columns,
}: Omit<SqlLabPostRequest['data'], 'dbId'> & { database: { id: number } }) {
return async function (dispatch: ThunkDispatch<any, undefined, AnyAction>) {
// Create a dataset object
try {
const {
json: { data },
} = await SupersetClient.post({
endpoint: '/superset/sqllab_viz/',
postPayload: {
data: {
schema,
sql,
dbId: database?.id,
templateParams,
datasourceName,
metrics: [],
columns,
},
},
});
// Update form_data to point to new dataset
dispatch(changeDatasource(data));
return data;
} catch (error) {
getClientErrorObject(error).then(e => {
dispatch(addDangerToast(e.error));
});
throw error;
}
};
}

export function changeDatasource(newDatasource: Dataset) {
return function (dispatch: Dispatch, getState: () => ExplorePageState) {
const {
Expand All @@ -44,6 +87,7 @@ export function changeDatasource(newDatasource: Dataset) {
export const datasourcesActions = {
setDatasource,
changeDatasource,
saveDataset,
};

export type AnyDatasourcesAction = SetDatasource;
Loading

0 comments on commit a913b18

Please sign in to comment.