Skip to content

Commit

Permalink
feat: Visualize SqlLab.Query model data in Explore 馃搱 (#20281)
Browse files Browse the repository at this point in the history
  • Loading branch information
hughhhh committed Jul 15, 2022
1 parent c70d102 commit e5e8867
Show file tree
Hide file tree
Showing 61 changed files with 2,511 additions and 611 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ describe('Test datatable', () => {
cy.get('.ant-empty-description').should('not.exist');
});
it('Datapane loads view samples', () => {
cy.intercept('/api/v1/dataset/*/samples?force=false').as('Samples');
cy.intercept(
'api/v1/explore/samples?force=false&datasource_type=table&datasource_id=*',
).as('Samples');
cy.contains('Samples')
.click()
.then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default class DatasourceKey {
constructor(key: string) {
const [idStr, typeStr] = key.split('__');
this.id = parseInt(idStr, 10);
this.type =
typeStr === 'table' ? DatasourceType.Table : DatasourceType.Druid;
this.type = DatasourceType.Table; // default to SqlaTable model
this.type = typeStr === 'query' ? DatasourceType.Query : this.type;
}

public toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type PhysicalColumn = string;
* Column information defined in datasource.
*/
export interface Column {
id: number;
id?: number;
type?: string;
type_generic?: GenericDataType;
column_name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { Metric } from './Metric';

export enum DatasourceType {
Table = 'table',
Druid = 'druid',
Query = 'query',
Dataset = 'dataset',
SlTable = 'sl_table',
Expand All @@ -47,11 +46,14 @@ export interface Datasource {
};
}

export const DEFAULT_METRICS = [
export const DEFAULT_METRICS: Metric[] = [
{
metric_name: 'COUNT(*)',
expression: 'COUNT(*)',
},
];

export const isValidDatasourceType = (datasource: DatasourceType) =>
Object.values(DatasourceType).includes(datasource);

export default {};
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ export type QueryResults = {
expanded_columns: QueryColumn[];
selected_columns: QueryColumn[];
query: { limit: number };
query_id?: number;
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,10 @@ import { DatasourceKey } from '@superset-ui/core';

describe('DatasourceKey', () => {
const tableKey = '5__table';
const druidKey = '5__druid';

it('should handle table data sources', () => {
const datasourceKey = new DatasourceKey(tableKey);
expect(datasourceKey.toString()).toBe(tableKey);
expect(datasourceKey.toObject()).toEqual({ id: 5, type: 'table' });
});

it('should handle druid data sources', () => {
const datasourceKey = new DatasourceKey(druidKey);
expect(datasourceKey.toString()).toBe(druidKey);
expect(datasourceKey.toObject()).toEqual({ id: 5, type: 'druid' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@ describe('buildQueryContext', () => {
expect(queryContext.result_format).toBe('json');
expect(queryContext.result_type).toBe('full');
});
it('should build datasource for druid sources and set force to true', () => {
const queryContext = buildQueryContext({
datasource: '5__druid',
granularity: 'ds',
viz_type: 'table',
force: true,
});
expect(queryContext.datasource.id).toBe(5);
expect(queryContext.datasource.type).toBe('druid');
expect(queryContext.force).toBe(true);
});
it('should build datasource for table sources with columns', () => {
const queryContext = buildQueryContext(
{
Expand Down
30 changes: 27 additions & 3 deletions superset-frontend/src/SqlLab/components/ResultSet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import Button from 'src/components/Button';
import shortid from 'shortid';
import { styled, t, QueryResponse } from '@superset-ui/core';
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
import {
ISaveableDatasource,
ISimpleColumn,
SaveDatasetModal,
} from 'src/SqlLab/components/SaveDatasetModal';
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
import ProgressBar from 'src/components/ProgressBar';
import Loading from 'src/components/Loading';
Expand Down Expand Up @@ -220,6 +224,15 @@ export default class ResultSet extends React.PureComponent<
const { showSaveDatasetModal } = this.state;
const { query } = this.props;

const datasource: ISaveableDatasource = {
columns: query.columns as ISimpleColumn[],
name: query?.tab || 'Untitled',
dbId: 1,
sql: query.sql,
templateParams: query.templateParams,
schema: query.schema,
};

return (
<ResultSetControls>
<SaveDatasetModal
Expand All @@ -230,14 +243,25 @@ export default class ResultSet extends React.PureComponent<
modalDescription={t(
'Save this query as a virtual dataset to continue exploring',
)}
datasource={query}
datasource={datasource}
/>
<ResultSetButtons>
{this.props.visualize &&
this.props.database?.allows_virtual_table_explore && (
<ExploreResultsButton
database={this.props.database}
onClick={() => this.setState({ showSaveDatasetModal: true })}
onClick={() => {
// There is currently redux / state issue where sometimes a query will have serverId
// and other times it will not. We need this attribute consistently for this to work
// const qid = this.props?.query?.results?.query_id;
// if (qid) {
// // This will open explore using the query as datasource
// window.location.href = `/explore/?dataset_type=query&dataset_id=${qid}`;
// } else {
// this.setState({ showSaveDatasetModal: true });
// }
this.setState({ showSaveDatasetModal: true });
}}
/>
)}
{this.props.csv && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,42 @@
* under the License.
*/
import React from 'react';
import { QueryResponse, testQuery } from '@superset-ui/core';
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
import {
ISaveableDatasource,
SaveDatasetModal,
} from 'src/SqlLab/components/SaveDatasetModal';
import { render, screen } from 'spec/helpers/testing-library';
import { DatasourceType } from '@superset-ui/core';

const testQuery: ISaveableDatasource = {
name: 'unimportant',
dbId: 1,
sql: 'SELECT *',
columns: [
{
name: 'Column 1',
type: DatasourceType.Query,
is_dttm: false,
},
{
name: 'Column 3',
type: DatasourceType.Query,
is_dttm: false,
},
{
name: 'Column 2',
type: DatasourceType.Query,
is_dttm: true,
},
],
};

const mockedProps = {
visible: true,
onHide: () => {},
buttonTextOnSave: 'Save',
buttonTextOnOverwrite: 'Overwrite',
datasource: testQuery as QueryResponse,
datasource: testQuery,
};

describe('SaveDatasetModal RTL', () => {
Expand All @@ -36,6 +62,7 @@ describe('SaveDatasetModal RTL', () => {
const saveRadioBtn = screen.getByRole('radio', {
name: /save as new unimportant/i,
});

const fieldLabel = screen.getByText(/save as new/i);
const inputField = screen.getByRole('textbox');
const inputFieldText = screen.getByDisplayValue(/unimportant/i);
Expand Down

0 comments on commit e5e8867

Please sign in to comment.