style: DOCTYPE tag, and related CSS cleanup/refactoring (#10302)

This commit is contained in:
Evan Rusackas 2020-07-29 18:49:32 -07:00 committed by GitHub
parent e6e6b49372
commit 16459ad401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 247 additions and 195 deletions

View File

@ -26,25 +26,27 @@ describe('AdhocMetrics', () => {
it('Clear metric and set simple adhoc metric', () => {
const metric = 'sum(sum_girls)';
const metricName = 'Girl Births';
const metricName = 'Sum Girls';
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });
cy.get('[data-test=metrics]').within(() => {
cy.get('.Select__clear-indicator').click();
cy.get('.Select__control input').type('sum_girls');
cy.get('.Select__option--is-focused').trigger('mousedown').click();
});
cy.get('[data-test=metrics]').find('.Select__clear-indicator').click();
cy.get('#metrics-edit-popover').within(() => {
cy.get('.popover-title').within(() => {
cy.get('span').click();
cy.get('input').type(metricName);
});
cy.get('button').contains('Save').click();
});
cy.get('.Select__multi-value__label').contains(metricName);
cy.get('[data-test=metrics]')
.find('.Select__control input')
.type('sum_girls', { force: true });
cy.get('[data-test=metrics]')
.find('.Select__option--is-focused')
.trigger('mousedown')
.click();
cy.get('[data-test="AdhocMetricEditTitle#trigger"]').click();
cy.get('[data-test="AdhocMetricEditTitle#input"]').type(metricName);
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
cy.get('.metrics-select .metric-option').contains(metricName);
cy.get('button.query').click();
cy.verifySliceSuccess({
@ -59,20 +61,21 @@ describe('AdhocMetrics', () => {
cy.verifySliceSuccess({ waitAlias: '@postJson' });
// select column "num"
cy.get('[data-test=metrics]').within(() => {
cy.get('.Select__clear-indicator').click();
cy.get('.Select__control').click();
cy.get('.Select__control input').type('num');
cy.get('.option-label').contains(/^num$/).click();
});
cy.get('[data-test=metrics]').find('.Select__clear-indicator').click();
cy.get('[data-test=metrics]').find('.Select__control').click();
cy.get('[data-test=metrics]').find('.Select__control input').type('num');
cy.get('[data-test=metrics]').find('.option-label').last().click();
// add custom SQL
cy.get('#metrics-edit-popover').within(() => {
cy.get('#adhoc-metric-edit-tabs-tab-SQL').click();
cy.get('.ace_content').click();
cy.get('.ace_text-input').type('/COUNT(DISTINCT name)', { force: true });
cy.get('button').contains('Save').click();
});
cy.get('#adhoc-metric-edit-tabs-tab-SQL').click();
cy.get('#metrics-edit-popover').find('.ace_content').click();
cy.get('#metrics-edit-popover')
.find('.ace_text-input')
.type('/COUNT(DISTINCT name)', { force: true });
cy.get('#metrics-edit-popover').find('button').contains('Save').click();
cy.get('button.query').click();

View File

@ -30,14 +30,18 @@ describe('Advanced analytics', () => {
cy.get('.panel-title').contains('Advanced Analytics').click();
cy.get('[data-test=time_compare]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').type('28 days{enter}');
cy.get('[data-test=time_compare]').find('.Select__control').click();
cy.get('[data-test=time_compare]')
.find('input[type=text]')
.type('28 days{enter}');
cy.get('.Select__control').click();
cy.get('input[type=text]').type('364 days{enter}');
cy.get('.Select__multi-value__label').contains('364 days');
});
cy.get('[data-test=time_compare]').find('.Select__control').click();
cy.get('[data-test=time_compare]')
.find('input[type=text]')
.type('364 days{enter}');
cy.get('[data-test=time_compare]')
.find('.Select__multi-value__label')
.contains('364 days');
cy.get('button.query').click();
cy.wait('@postJson');

View File

@ -46,16 +46,10 @@ describe('Datasource control', () => {
cy.get('.modal-footer button').contains('Save').click();
cy.get('.modal-footer button').contains('OK').click();
// select new metric
cy.get('.metrics-select:eq(0)').click();
cy.get('.metrics-select:eq(0) input[type="text"]')
cy.get('[data-test=metrics]')
.find('.Select__control input')
.focus()
.type(newMetricName);
cy.get('.metrics-select:eq(0) .Select__menu .Select__option')
.contains(newMetricName)
.click();
cy.get('.metrics-select:eq(0) .Select__multi-value__label')
.contains(newMetricName)
.click();
.type(newMetricName, { force: true });
// delete metric
cy.get('#datasource_menu').click();
cy.get('a').contains('Edit Datasource').click();

View File

@ -35,8 +35,6 @@ describe('Edit FilterBox Chart', () => {
it('should work with default date filter', () => {
verify(VIZ_DEFAULTS);
// Filter box should default to having a date filter with no filter selected
cy.get('div.filter_box').within(() => {
cy.get('span').contains('No filter');
});
cy.get('div.filter_box').contains('No filter');
});
});

View File

@ -46,9 +46,9 @@ describe('Visualization > Line', () => {
});
it('should allow negative values in Y bounds', () => {
cy.get('#controlSections-tab-display').click();
cy.get('#controlSections-tab-display').click().wait(1000);
cy.get('span').contains('Y Axis Bounds').scrollIntoView();
cy.get('input[placeholder="Min"]').type('-0.1', { delay: 100 });
cy.get('input[placeholder="Min"]').type('-0.1', { delay: 100 }).wait(1000);
cy.get('.alert-warning').should('not.exist');
});

View File

@ -50,6 +50,9 @@ const ListViewStyles = styled.div`
background: white;
position: sticky;
top: 0;
&:first-of-type {
padding-left: ${({ theme }) => theme.gridUnit * 4}px;
}
}
}
}
@ -152,6 +155,11 @@ const ListViewStyles = styled.div`
overflow: hidden;
white-space: nowrap;
max-width: 300px;
line-height: 1;
vertical-align: middle;
&:first-of-type {
padding-left: ${({ theme }) => theme.gridUnit * 4}px;
}
}
.sort-icon {

View File

@ -271,6 +271,7 @@ export default class AdhocMetricEditPopover extends React.Component {
className="adhoc-metric-edit-tab"
eventKey={EXPRESSION_TYPES.SQL}
title="Custom SQL"
data-test="adhoc-metric-edit-tab#custom"
>
{this.props.datasourceType !== 'druid' ? (
<FormGroup>
@ -304,11 +305,16 @@ export default class AdhocMetricEditPopover extends React.Component {
bsStyle={hasUnsavedChanges && stateIsValid ? 'primary' : 'default'}
bsSize="small"
className="m-r-5"
data-test="AdhocMetricEdit#save"
onClick={this.onSave}
>
Save
</Button>
<Button bsSize="small" onClick={this.props.onClose}>
<Button
bsSize="small"
onClick={this.props.onClose}
data-test="AdhocMetricEdit#cancel"
>
Close
</Button>
<i

View File

@ -70,6 +70,7 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
value={adhocMetric.hasCustomLabel ? adhocMetric.label : ''}
autoFocus
onChange={onChange}
data-test="AdhocMetricEditTitle#input"
/>
) : (
<OverlayTrigger
@ -81,7 +82,10 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
onBlur={this.onBlur}
className="AdhocMetricEditPopoverTitle"
>
<span className="inline-editable">
<span
className="inline-editable"
data-test="AdhocMetricEditTitle#trigger"
>
{adhocMetric.hasCustomLabel ? adhocMetric.label : 'My Metric'}
&nbsp;
<i

View File

@ -23,6 +23,7 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Alert, Tab, Tabs } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
import styled from '@superset-ui/style';
import ControlPanelSection from './ControlPanelSection';
import ControlRow from './ControlRow';
@ -40,6 +41,25 @@ const propTypes = {
isDatasourceMetaLoading: PropTypes.bool.isRequired,
};
const Styles = styled.div`
max-height: 100%;
.remove-alert {
cursor: 'pointer';
}
#controlSections {
display: flex;
flex-direction: column;
max-height: 100%;
}
.nav-tabs {
flex: 0 0 1;
}
.tab-content {
overflow: auto;
flex: 1 1 100%;
}
`;
class ControlPanelsContainer extends React.Component {
constructor(props) {
super(props);
@ -145,6 +165,7 @@ class ControlPanelsContainer extends React.Component {
</ControlPanelSection>
);
}
render() {
const querySectionsToRender = [];
const displaySectionsToRender = [];
@ -170,32 +191,30 @@ class ControlPanelsContainer extends React.Component {
});
return (
<div className="scrollbar-container">
<div className="scrollbar-content">
{this.props.alert && (
<Alert bsStyle="warning">
{this.props.alert}
<i
role="button"
tabIndex={0}
className="fa fa-close pull-right"
onClick={this.removeAlert}
style={{ cursor: 'pointer' }}
/>
</Alert>
)}
<Tabs id="controlSections">
<Tab eventKey="query" title={t('Data')}>
{querySectionsToRender.map(this.renderControlPanelSection)}
<Styles>
{this.props.alert && (
<Alert bsStyle="warning">
{this.props.alert}
<i
role="button"
tabIndex={0}
className="fa fa-close pull-right"
onClick={this.removeAlert}
style={{ cursor: 'pointer' }}
/>
</Alert>
)}
<Tabs id="controlSections">
<Tab eventKey="query" title={t('Data')}>
{querySectionsToRender.map(this.renderControlPanelSection)}
</Tab>
{displaySectionsToRender.length > 0 && (
<Tab eventKey="display" title={t('Customize')}>
{displaySectionsToRender.map(this.renderControlPanelSection)}
</Tab>
{displaySectionsToRender.length > 0 && (
<Tab eventKey="display" title={t('Customize')}>
{displaySectionsToRender.map(this.renderControlPanelSection)}
</Tab>
)}
</Tabs>
</div>
</div>
)}
</Tabs>
</Styles>
);
}
}

View File

@ -18,8 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { Panel } from 'react-bootstrap';
import { ParentSize } from '@vx/responsive';
import styled from '@superset-ui/style';
import { chartPropShape } from '../../dashboard/util/propShapes';
import ChartContainer from '../../chart/ChartContainer';
import ExploreChartHeader from './ExploreChartHeader';
@ -49,6 +49,19 @@ const propTypes = {
triggerRender: PropTypes.bool,
};
const Styles = styled.div`
background-color: ${({ theme }) => theme.colors.grayscale.light5};
padding: ${({ theme }) => theme.gridUnit * 4}px;
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
align-content: stretch;
div:last-of-type {
flex-basis: 100%;
}
`;
class ExploreChartPanel extends React.PureComponent {
renderChart() {
const { chart } = this.props;
@ -113,13 +126,12 @@ class ExploreChartPanel extends React.PureComponent {
chart={this.props.chart}
/>
);
return (
<div className="chart-container">
<Panel style={{ height: this.props.height }}>
<Panel.Heading>{header}</Panel.Heading>
<Panel.Body>{this.renderChart()}</Panel.Body>
</Panel>
</div>
<Styles className="chart-container">
<div>{header}</div>
<div>{this.renderChart()}</div>
</Styles>
);
}
}

View File

@ -21,6 +21,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import styled from '@superset-ui/style';
import { t } from '@superset-ui/translation';
import ExploreChartPanel from './ExploreChartPanel';
@ -40,20 +41,6 @@ import {
LOG_ACTIONS_MOUNT_EXPLORER,
LOG_ACTIONS_CHANGE_EXPLORE_CONTROLS,
} from '../../logger/LogUtils';
import Hotkeys from '../../components/Hotkeys';
// Prolly need to move this to a global context
const keymap = {
RUN: 'ctrl + r, ctrl + enter',
SAVE: 'ctrl + s',
};
const getHotKeys = () =>
Object.keys(keymap).map(k => ({
name: k,
descr: keymap[k],
key: k,
}));
const propTypes = {
actions: PropTypes.object.isRequired,
@ -70,6 +57,25 @@ const propTypes = {
impressionId: PropTypes.string,
};
const Styles = styled.div`
height: ${({ height }) => height};
min-height: ${({ height }) => height};
overflow: hidden;
text-align: left;
position: relative;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: stretch;
.control-pane {
display: flex;
flex-direction: column;
padding: 0 ${({ theme }) => 2 * theme.gridUnit}px;
max-height: 100%;
}
`;
class ExploreViewContainer extends React.Component {
constructor(props) {
super(props);
@ -325,12 +331,9 @@ class ExploreViewContainer extends React.Component {
if (this.props.standalone) {
return this.renderChartContainer();
}
return (
<div
id="explore-container"
className="container-fluid"
style={{ height: this.state.height, overflow: 'hidden' }}
>
<Styles id="explore-container" height={this.state.height}>
{this.state.showModal && (
<SaveModal
onHide={this.toggleModal}
@ -339,45 +342,27 @@ class ExploreViewContainer extends React.Component {
sliceName={this.props.sliceName}
/>
)}
<div className="row">
<div className="col-sm-4">
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
}}
>
<QueryAndSaveBtns
canAdd={!!(this.props.can_add || this.props.can_overwrite)}
onQuery={this.onQuery}
onSave={this.toggleModal}
onStop={this.onStop}
loading={this.props.chart.chartStatus === 'loading'}
chartIsStale={this.state.chartIsStale}
errorMessage={this.renderErrorMessage()}
datasourceType={this.props.datasource_type}
/>
<div className="m-l-5 text-muted">
<Hotkeys
header="Keyboard shortcuts"
hotkeys={getHotKeys()}
placement="right"
/>
</div>
</div>
<br />
<ControlPanelsContainer
actions={this.props.actions}
form_data={this.props.form_data}
controls={this.props.controls}
datasource_type={this.props.datasource_type}
isDatasourceMetaLoading={this.props.isDatasourceMetaLoading}
/>
</div>
<div className="col-sm-8">{this.renderChartContainer()}</div>
<div className="col-sm-4 control-pane">
<QueryAndSaveBtns
canAdd={!!(this.props.can_add || this.props.can_overwrite)}
onQuery={this.onQuery}
onSave={this.toggleModal}
onStop={this.onStop}
loading={this.props.chart.chartStatus === 'loading'}
chartIsStale={this.state.chartIsStale}
errorMessage={this.renderErrorMessage()}
datasourceType={this.props.datasource_type}
/>
<ControlPanelsContainer
actions={this.props.actions}
form_data={this.props.form_data}
controls={this.props.controls}
datasource_type={this.props.datasource_type}
isDatasourceMetaLoading={this.props.isDatasourceMetaLoading}
/>
</div>
</div>
<div className="col-sm-8">{this.renderChartContainer()}</div>
</Styles>
);
}
}
@ -433,6 +418,7 @@ function mapDispatchToProps(dispatch) {
}
export { ExploreViewContainer };
export default connect(
mapStateToProps,
mapDispatchToProps,

View File

@ -1,21 +0,0 @@
/**
* 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.
*/
.save-btn {
width: 100px;
}

View File

@ -21,9 +21,10 @@ import PropTypes from 'prop-types';
import { ButtonGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
import classnames from 'classnames';
import { t } from '@superset-ui/translation';
import styled from '@superset-ui/style';
import Button from '../../components/Button';
import './QueryAndSaveBtns.css';
import Hotkeys from '../../components/Hotkeys';
const propTypes = {
canAdd: PropTypes.bool.isRequired,
@ -41,6 +42,30 @@ const defaultProps = {
disabled: false,
};
// Prolly need to move this to a global context
const keymap = {
RUN: 'ctrl + r, ctrl + enter',
SAVE: 'ctrl + s',
};
const getHotKeys = () =>
Object.keys(keymap).map(k => ({
name: k,
descr: keymap[k],
key: k,
}));
const Styles = styled.div`
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: ${({ theme }) => 2 * theme.gridUnit}px;
.save-btn {
width: 100px;
}
`;
export default function QueryAndSaveBtns({
canAdd,
onQuery,
@ -79,33 +104,42 @@ export default function QueryAndSaveBtns({
);
return (
<div>
<ButtonGroup className="query-and-save">
{qryOrStopButton}
<Button
className={saveClasses}
data-target="#save_modal"
data-toggle="modal"
disabled={saveButtonDisabled}
onClick={onSave}
>
<i className="fa fa-plus-circle" /> Save
</Button>
</ButtonGroup>
{errorMessage && (
<span>
{' '}
<OverlayTrigger
placement="right"
overlay={
<Tooltip id={'query-error-tooltip'}>{errorMessage}</Tooltip>
}
<Styles>
<div>
<ButtonGroup className="query-and-save">
{qryOrStopButton}
<Button
className={saveClasses}
data-target="#save_modal"
data-toggle="modal"
disabled={saveButtonDisabled}
onClick={onSave}
>
<i className="fa fa-exclamation-circle text-danger fa-lg" />
</OverlayTrigger>
</span>
)}
</div>
<i className="fa fa-plus-circle" /> Save
</Button>
</ButtonGroup>
{errorMessage && (
<span>
{' '}
<OverlayTrigger
placement="right"
overlay={
<Tooltip id={'query-error-tooltip'}>{errorMessage}</Tooltip>
}
>
<i className="fa fa-exclamation-circle text-danger fa-lg" />
</OverlayTrigger>
</span>
)}
</div>
<div className="m-l-5 text-muted">
<Hotkeys
header="Keyboard shortcuts"
hotkeys={getHotKeys()}
placement="right"
/>
</div>
</Styles>
);
}

View File

@ -444,6 +444,9 @@ table.table-no-hover tr:hover {
line-height: 2px;
border-radius: 50%;
box-shadow: 2px 2px 4px -1px fade(@darkest, @opacity-light);
i {
width: 10px;
}
}
iframe {

View File

@ -21,7 +21,7 @@
{% from 'superset/partials/asset_bundle.html' import css_bundle, js_bundle with context %}
{% set favicons = appbuilder.app.config['FAVICONS'] %}
<!DOCTYPE html>
<html>
<head>
<title>

View File

@ -520,7 +520,7 @@
</div>
<div class="row">
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel panel-default f1">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>

View File

@ -16,6 +16,7 @@
specific language governing permissions and limitations
under the License.
#}
<!DOCTYPE html>
<html>
<head>
</head>

View File

@ -803,7 +803,7 @@
<div class="row">
<div class="col-lg-6">
<h2 id="nav-tabs">Tabs</h2>
<div class="panel panel-default">
<div class="panel panel-default f2">
<div class="panel-body">
<div class="bs-component">
<ul class="nav nav-tabs">
@ -1184,13 +1184,13 @@
<div class="row">
<div class="col-lg-4">
<div class="bs-component">
<div class="panel panel-default">
<div class="panel panel-default f3">
<div class="panel-body">
Basic panel
</div>
</div>
<div class="panel panel-default">
<div class="panel panel-default f4">
<div class="panel-body">
Panel content
</div>
@ -1200,7 +1200,7 @@
</div>
<div class="col-lg-4">
<div class="bs-component">
<div class="panel panel-default">
<div class="panel panel-default f5">
<div class="panel-heading">
<h3 class="panel-title">Panel default</h3>
</div>

View File

@ -15,14 +15,15 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
#}
#}}
<!DOCTYPE html>
<html>
<body>
<h1>Sorry, something went wrong</h1>
<h3>500 - Internal Server Error</h3>
<hr>
<hr />
<h2>Stacktrace</h2>
<hr>
<hr />
<code>
<pre>
{{ error_msg }}