Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(explore-datasource): add new datasource tab to explore view #12008

Merged
merged 49 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3c28ed5
update to datsource tab
pkdotson Dec 10, 2020
e48252a
second update
pkdotson Dec 11, 2020
cb6efe7
style updates
pkdotson Dec 11, 2020
cd12006
update style and fix metrics bug
pkdotson Dec 11, 2020
87eb348
updates to datsource panel
pkdotson Dec 14, 2020
6208894
backgrounds and borders
rusackas Dec 14, 2020
6f3d07e
more updates
pkdotson Dec 14, 2020
2c44f0a
shuffling some paddings around
rusackas Dec 14, 2020
1fbf5e1
more updates
pkdotson Dec 15, 2020
0b84909
moving some more paddings around!
rusackas Dec 15, 2020
3a34260
Fixing sidebar width
rusackas Dec 15, 2020
723db22
using Global to adjust body layout
rusackas Dec 15, 2020
195b407
update test and fix bug
pkdotson Dec 15, 2020
cf68d07
removing hotkeys
rusackas Dec 15, 2020
89c31d4
layout fixes for short content, simplifying some class names
rusackas Dec 15, 2020
6106e77
more styles
pkdotson Dec 15, 2020
d019125
add tooltip to collapse and div clickable
pkdotson Dec 15, 2020
55b0226
more updates
pkdotson Dec 15, 2020
ea47f82
more updates for styles and add list component
pkdotson Dec 16, 2020
ba580d2
update from comments
pkdotson Dec 16, 2020
507586c
vising cosmetic issue with line-wrapping drop down caret on controls …
rusackas Dec 16, 2020
5132853
controls area scrolling properly again.
rusackas Dec 16, 2020
c17abcf
change lists to old list and updates from comments
pkdotson Dec 17, 2020
dac1ade
border radius from theme
rusackas Dec 17, 2020
24193d1
add length field and updates from comments
pkdotson Dec 17, 2020
c191dfb
more changes from comments
pkdotson Dec 17, 2020
49559ef
integrate health with new control
pkdotson Dec 17, 2020
7777b4b
change callapse back from stylsheet more udpates
pkdotson Dec 17, 2020
99a1fe5
substitution string
rusackas Dec 17, 2020
fb4b175
more substitution strings
rusackas Dec 17, 2020
360dd6d
fix tests
pkdotson Dec 17, 2020
9bdf748
datasource alignment
pkdotson Dec 17, 2020
0a0e045
taking margin off the search input
rusackas Dec 17, 2020
9a15949
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
rusackas Dec 17, 2020
4c430c0
update input to flex
pkdotson Dec 17, 2020
f73fc00
fix lint
pkdotson Dec 17, 2020
d418cd9
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
pkdotson Dec 17, 2020
72369fd
adjusting column/metric label stylng
rusackas Dec 17, 2020
7e53dcb
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
rusackas Dec 17, 2020
5494124
fixing scrollable area layout, one more color variable
rusackas Dec 18, 2020
369aded
simplifying some styles
rusackas Dec 18, 2020
ab77687
nixing a bad left margin
rusackas Dec 18, 2020
1f1b2a8
Using gridunit for padding
rusackas Dec 18, 2020
c11aa52
using gridUnit for padding
rusackas Dec 18, 2020
81a04f3
define types for datsource panel
pkdotson Dec 18, 2020
499d3eb
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
pkdotson Dec 18, 2020
070ab28
fixing a padding issue
rusackas Dec 18, 2020
8d43ae5
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
rusackas Dec 18, 2020
171e45a
Merge branch 'phillip/explore-datasource' of https://github.com/prese…
pkdotson Dec 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Datasource control', () => {
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });

cy.get('[data-test="open-datasource-tab').click({ force: true });
cy.get('[data-test="datasource-menu-trigger"]').click();

cy.get('script').then(nodes => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ describe('ControlPanelSection', () => {
});

it('renders a label if present', () => {
expect(wrapper.find(Panel.Title).dive().text()).toContain('my label');
expect(
wrapper
.find('[data-test="clickable-control-panel-section-title"]')
.text(),
).toContain('my label');
});

it('renders a InfoTooltipWithTrigger if label and tooltip is present', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ describe('DatasourceControl', () => {

it('should render health check message', () => {
const wrapper = setup();
const alert = wrapper.find(Icon).first();
expect(alert.prop('name')).toBe('alert-solid');
const alert = wrapper.find(Icon);
expect(alert.at(1).prop('name')).toBe('alert-solid');
const tooltip = wrapper.find(Tooltip).at(1);
expect(tooltip.prop('title')).toBe(
defaultProps.datasource.health_check_message,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* 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 from 'react';
import { render, screen } from '@testing-library/react';
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
import DatasourcePanel from 'src/explore/components/DatasourcePanel';

describe('datasourcepanel', () => {
const datasource = {
name: 'birth_names',
type: 'table',
uid: '1__table',
id: 1,
columns: [],
metrics: [],
database: {
backend: 'mysql',
name: 'main',
},
};
const props = {
datasource,
controls: {
datasource: {
validationErrors: null,
mapStateToProps: () => null,
type: 'DatasourceControl',
label: 'hello',
datasource,
},
},
actions: null,
};
it('should render', () => {
const { container } = render(
<ThemeProvider theme={supersetTheme}>
<DatasourcePanel {...props} />
</ThemeProvider>,
);
expect(container).toBeVisible();
});

it('should display items in controls', () => {
render(
<ThemeProvider theme={supersetTheme}>
<DatasourcePanel {...props} />
</ThemeProvider>,
);
expect(screen.getByText('birth_names')).toBeTruthy();
expect(screen.getByText('Columns')).toBeTruthy();
expect(screen.getByText('Metrics')).toBeTruthy();
});
});
11 changes: 10 additions & 1 deletion superset-frontend/src/explore/components/ControlPanelSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Panel } from 'react-bootstrap';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { styled } from '@superset-ui/core';

const propTypes = {
label: PropTypes.string,
Expand All @@ -36,6 +37,14 @@ const defaultProps = {
hasErrors: false,
};

const StyledPanelTitle = styled(Panel.Title)`
& > div {
display: flex;
align-items: center;
justify-content: space-between;
}
`;

export default class ControlPanelSection extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -94,7 +103,7 @@ export default class ControlPanelSection extends React.Component {
onToggle={this.toggleExpand}
>
<Panel.Heading>
<Panel.Title>{this.renderHeader()}</Panel.Title>
<StyledPanelTitle>{this.renderHeader()}</StyledPanelTitle>
</Panel.Heading>
<Panel.Collapse>
<Panel.Body>{this.props.children}</Panel.Body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,11 @@ class ControlPanelsContainer extends React.Component {
// When the item is a React element
return controlItem;
}
if (controlItem.name && controlItem.config) {
if (
controlItem.name &&
controlItem.config &&
controlItem.name !== 'datasource'
pkdotson marked this conversation as resolved.
Show resolved Hide resolved
) {
return this.renderControl(controlItem);
}
return null;
Expand Down Expand Up @@ -204,7 +208,6 @@ class ControlPanelsContainer extends React.Component {
displaySectionsToRender.push(section);
}
});

const showCustomizeTab = displaySectionsToRender.length > 0;
return (
<Styles>
Expand Down
209 changes: 209 additions & 0 deletions superset-frontend/src/explore/components/DatasourcePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/**
* 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, QueryFormData } from '@superset-ui/core';
import { Collapse } from 'src/common/components';
import {
ColumnOption,
MetricOption,
ControlType,
} from '@superset-ui/chart-controls';
import { ExploreActions } from '../actions/exploreActions';
import Control from './Control';

interface DatasourceControl {
validationErrors: any;
mapStateToProps: QueryFormData;
type: ControlType;
label: string;
datasource?: DatasourceControl;
}

interface Props {
datasource: {
columns: Array<any>;
metrics: Array<any>;
};
controls: {
datasource: DatasourceControl;
};
actions: Partial<ExploreActions> & Pick<ExploreActions, 'setControlValue'>;
}

const DatasourceContainer = styled.div`
background-color: ${({ theme }) => theme.colors.grayscale.light4};
position: relative;
height: 100%;
display: flex;
flex-direction: column;
max-height: 100%;
.ant-collapse {
height: auto;
border-bottom: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
padding-bottom: 8px;
rusackas marked this conversation as resolved.
Show resolved Hide resolved
background-color: ${({ theme }) => theme.colors.grayscale.light4};
}
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
padding-left: 10px;
rusackas marked this conversation as resolved.
Show resolved Hide resolved
padding-bottom: 0px;
}
.form-control.input-sm {
margin-bottom: ${({ theme }) => theme.gridUnit * 3}px;
}
.ant-collapse-item {
background-color: ${({ theme }) => theme.colors.grayscale.light4};
.anticon.anticon-right.ant-collapse-arrow > svg {
transform: rotate(90deg) !important;
pkdotson marked this conversation as resolved.
Show resolved Hide resolved
margin-right: ${({ theme }) => theme.gridUnit * -2}px;
}
}
.ant-collapse-item.ant-collapse-item-active {
.anticon.anticon-right.ant-collapse-arrow > svg {
transform: rotate(-90deg) !important;
}
.ant-collapse-header {
border: 0;
}
}
.header {
font-size: ${({ theme }) => theme.typography.sizes.l}px;
margin-left: ${({ theme }) => theme.gridUnit * -2}px;
}
.ant-collapse-content-box {
padding-bottom: 0px;
& > div {
margin-left: -14px;
}
}
.metric-option .option-label {
margin-left: ${({ theme }) => theme.gridUnit * -5}px;
}
.field-selections {
padding: ${({ theme }) => 2 * theme.gridUnit}px;
overflow: auto;
}
.field-length {
margin-top: -3px;
margin-bottom: ${({ theme }) => theme.gridUnit * 2}px;
font-size: ${({ theme }) => theme.typography.sizes.s}px;
color: ${({ theme }) => theme.colors.grayscale.light1};
}
.form-control.input-sm {
margin-bottom: 0;
}
.type-label {
font-weight: ${({ theme }) => theme.typography.weights.light};
font-size: ${({ theme }) => theme.typography.sizes.s}px;
color: ${({ theme }) => theme.colors.grayscale.base};
}
.Control {
padding-bottom: 0;
}
`;

const DataSourcePanel = ({
datasource,
controls: { datasource: datasourceControl },
actions,
}: Props) => {
const { columns, metrics } = datasource;
const [lists, setList] = useState({
columns,
metrics,
});
const search = ({ target: { value } }: { target: { value: string } }) => {
if (value === '') {
setList({ columns, metrics });
return;
}
const filteredColumns = lists.columns.filter(
column => column.column_name.indexOf(value) !== -1,
);
const filteredMetrics = lists.metrics.filter(
metric => metric.metric_name.indexOf(value) !== -1,
);
setList({ columns: filteredColumns, metrics: filteredMetrics });
};
useEffect(() => {
setList({
columns,
metrics,
});
}, [datasource]);

const metricSlice = lists.metrics.slice(0, 50);
const columnSlice = lists.columns.slice(0, 50);
pkdotson marked this conversation as resolved.
Show resolved Hide resolved

return (
<DatasourceContainer>
<Control
{...datasourceControl}
name="datasource"
validationErrors={datasourceControl.validationErrors}
actions={actions}
formData={datasourceControl.mapStateToProps}
/>
<div className="field-selections">
<input
type="text"
onChange={search}
className="form-control input-sm"
placeholder={t('Search Metrics & Columns')}
/>
<Collapse
accordion
bordered={false}
defaultActiveKey={['column', 'metrics']}
expandIconPosition="right"
>
<Collapse.Panel
header={<span className="header">{t('Columns')}</span>}
key="column"
>
<div className="field-length">
{t(`Showing %s of %s`, columnSlice.length, columns.length)}
</div>
{columnSlice.map(col => (
<div key={col.column_name} className="column">
<ColumnOption column={col} showType />
</div>
))}
</Collapse.Panel>
</Collapse>
<Collapse accordion bordered={false} expandIconPosition="right">
<Collapse.Panel
header={<span className="header">{t('Metrics')}</span>}
key="metrics"
>
<div className="field-length">
{t(`Showing %s of %s`, metricSlice.length, metrics.length)}
</div>
{metricSlice.map(m => (
<div key={m.column_name} className="column">
<MetricOption metric={m} showType />
</div>
))}
</Collapse.Panel>
</Collapse>
</div>
</DatasourceContainer>
);
};

export default DataSourcePanel;
Loading