style: push bootstrap theme towards SIP-34 styles (#10056)

* feat: cartel theme

* piling

* more tweaks

* Make things look better

* lint

* fix tests

* paint it black

* tweaks
This commit is contained in:
Maxime Beauchemin 2020-06-18 15:01:58 -07:00 committed by GitHub
parent 8e23d4f369
commit a6390afb89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 148 additions and 90 deletions

View File

@ -45,7 +45,7 @@ combine_as_imports = true
include_trailing_comma = true include_trailing_comma = true
line_length = 88 line_length = 88
known_first_party = superset known_first_party = superset
known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,contextlib2,croniter,cryptography,dateutil,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,geohash,geopy,humanize,isodate,jinja2,markdown,markupsafe,marshmallow,msgpack,numpy,pandas,parsedatetime,pathlib2,polyline,prison,pyarrow,pyhive,pytz,retry,selenium,setuptools,simplejson,sphinx_rtd_theme,sqlalchemy,sqlalchemy_utils,sqlparse,werkzeug,wtforms,wtforms_json,yaml known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,contextlib2,croniter,cryptography,dateutil,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,geohash,geopy,humanize,isodate,jinja2,markdown,markupsafe,marshmallow,msgpack,numpy,pandas,parsedatetime,pathlib2,polyline,prison,pyarrow,pyhive,pytz,retry,selenium,setuptools,simplejson,slack,sphinx_rtd_theme,sqlalchemy,sqlalchemy_utils,sqlparse,werkzeug,wtforms,wtforms_json,yaml
multi_line_output = 3 multi_line_output = 3
order_by_type = false order_by_type = false

View File

@ -43,12 +43,10 @@ export default () => {
const initialTabCount = tabListA.length; const initialTabCount = tabListA.length;
// open the tab dropdown to remove // open the tab dropdown to remove
cy.get( cy.get('#a11y-query-editor-tabs > ul > li .dropdown-toggle').click();
'#a11y-query-editor-tabs > ul > li:first button:nth-child(2)',
).click();
// first item is close // first item is close
cy.get('#a11y-query-editor-tabs > ul > li:first ul li a').eq(0).click(); cy.get('#a11y-query-editor-tabs .close-btn a').click();
cy.get('#a11y-query-editor-tabs > ul > li').should( cy.get('#a11y-query-editor-tabs > ul > li').should(
'have.length', 'have.length',

View File

@ -49,7 +49,7 @@ describe('QueryAndSaveButtons', () => {
}); });
it('renders buttons with correct text', () => { it('renders buttons with correct text', () => {
expect(wrapper.find(Button).contains(' Run Query')).toBe(true); expect(wrapper.find(Button).contains('Run')).toBe(true);
expect(wrapper.find(Button).contains(' Save')).toBe(true); expect(wrapper.find(Button).contains(' Save')).toBe(true);
}); });

View File

@ -109,7 +109,7 @@ describe('SqlEditor', () => {
it('allows toggling autocomplete', () => { it('allows toggling autocomplete', () => {
const wrapper = shallow(<SqlEditor {...mockedProps} />); const wrapper = shallow(<SqlEditor {...mockedProps} />);
expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(true); expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(true);
wrapper.find(Checkbox).props().onChange(); wrapper.find('.autocomplete').simulate('click');
expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(false); expect(wrapper.find(AceEditorWrapper).props().autocomplete).toBe(false);
}); });
}); });

View File

@ -42,7 +42,7 @@ const RunQueryActionButton = ({
stopQuery = NO_OP, stopQuery = NO_OP,
sql, sql,
}: Props) => { }: Props) => {
const runBtnText = selectedText ? t('Run Selected Query') : t('Run Query'); const runBtnText = selectedText ? t('Run Selected Query') : t('Run');
const btnStyle = selectedText ? 'warning' : 'primary'; const btnStyle = selectedText ? 'warning' : 'primary';
const shouldShowStopBtn = const shouldShowStopBtn =
!!queryState && ['running', 'pending'].indexOf(queryState) > -1; !!queryState && ['running', 'pending'].indexOf(queryState) > -1;
@ -68,7 +68,7 @@ const RunQueryActionButton = ({
tooltip={t('Run query asynchronously (Ctrl + ↵)')} tooltip={t('Run query asynchronously (Ctrl + ↵)')}
disabled={!sql.trim()} disabled={!sql.trim()}
> >
<i className="fa fa-table" /> {runBtnText} <i className="fa fa-bolt" /> {runBtnText}
</Button> </Button>
); );
} }

View File

@ -172,7 +172,7 @@ class SaveQuery extends React.PureComponent {
className="toggleSave" className="toggleSave"
onClick={this.toggleSave} onClick={this.toggleSave}
> >
<i className="fa fa-save" /> {t('Save Query')} <i className="fa fa-save" /> {t('Save')}
</Button> </Button>
} }
bsSize="small" bsSize="small"

View File

@ -112,7 +112,7 @@ class ShareSqlLabQuery extends React.Component {
overlay={this.renderPopover()} overlay={this.renderPopover()}
> >
<Button bsSize="small" className="toggleSave"> <Button bsSize="small" className="toggleSave">
<i className="fa fa-clipboard" /> {t('Share Query')} <i className="fa fa-share" /> {t('Share')}
</Button> </Button>
</OverlayTrigger> </OverlayTrigger>
); );

View File

@ -20,7 +20,6 @@ import React from 'react';
import { CSSTransition } from 'react-transition-group'; import { CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
Checkbox,
FormGroup, FormGroup,
InputGroup, InputGroup,
Form, Form,
@ -35,6 +34,7 @@ import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle'; import throttle from 'lodash/throttle';
import Button from '../../components/Button'; import Button from '../../components/Button';
import Checkbox from '../../components/Checkbox';
import LimitControl from './LimitControl'; import LimitControl from './LimitControl';
import TemplateParamsEditor from './TemplateParamsEditor'; import TemplateParamsEditor from './TemplateParamsEditor';
import SouthPane from './SouthPane'; import SouthPane from './SouthPane';
@ -509,16 +509,13 @@ class SqlEditor extends React.PureComponent {
</Form> </Form>
</div> </div>
<div className="rightItems"> <div className="rightItems">
<span> <Button
<Checkbox className="autocomplete"
checked={this.state.autocompleteEnabled} onClick={this.handleToggleAutocompleteEnabled}
inline >
title={t('Autocomplete')} <Checkbox checked={this.state.autocompleteEnabled} />{' '}
onChange={this.handleToggleAutocompleteEnabled} {t('Autocomplete')}
> </Button>{' '}
{t('Autocomplete')}
</Checkbox>
</span>
<TemplateParamsEditor <TemplateParamsEditor
language="json" language="json"
onChange={params => { onChange={params => {

View File

@ -288,46 +288,60 @@ class TabbedSqlEditors extends React.PureComponent {
</> </>
); );
const tabTitle = ( const tabTitle = (
<SplitButton <>
bsSize="small" <span className="ddbtn-tab">{title}</span>
id={'ddbtn-tab-' + i} {isSelected && (
className="ddbtn-tab" <SplitButton
title={title} bsSize="small"
> id={'ddbtn-tab-' + i}
<MenuItem eventKey="1" onClick={() => this.removeQueryEditor(qe)}> className="ddbtn-tab"
<div className="icon-container"> title="&nbsp;"
<i className="fa fa-close" /> >
</div> <MenuItem
{t('Close tab')} className="close-btn"
</MenuItem> eventKey="1"
<MenuItem eventKey="2" onClick={() => this.renameTab(qe)}> onClick={() => this.removeQueryEditor(qe)}
<div className="icon-container"> >
<i className="fa fa-i-cursor" /> <div className="icon-container">
</div> <i className="fa fa-close" />
{t('Rename tab')} </div>
</MenuItem> {t('Close tab')}
<MenuItem eventKey="3" onClick={this.toggleLeftBar}> </MenuItem>
<div className="icon-container"> <MenuItem eventKey="2" onClick={() => this.renameTab(qe)}>
<i className="fa fa-cogs" /> <div className="icon-container">
</div> <i className="fa fa-i-cursor" />
{this.state.hideLeftBar ? t('Expand tool bar') : t('Hide tool bar')} </div>
</MenuItem> {t('Rename tab')}
<MenuItem </MenuItem>
eventKey="4" <MenuItem eventKey="3" onClick={this.toggleLeftBar}>
onClick={() => this.removeAllOtherQueryEditors(qe)} <div className="icon-container">
> <i className="fa fa-cogs" />
<div className="icon-container"> </div>
<i className="fa fa-times-circle-o" /> {this.state.hideLeftBar
</div> ? t('Expand tool bar')
{t('Close all other tabs')} : t('Hide tool bar')}
</MenuItem> </MenuItem>
<MenuItem eventKey="5" onClick={() => this.duplicateQueryEditor(qe)}> <MenuItem
<div className="icon-container"> eventKey="4"
<i className="fa fa-files-o" /> onClick={() => this.removeAllOtherQueryEditors(qe)}
</div> >
{t('Duplicate tab')} <div className="icon-container">
</MenuItem> <i className="fa fa-times-circle-o" />
</SplitButton> </div>
{t('Close all other tabs')}
</MenuItem>
<MenuItem
eventKey="5"
onClick={() => this.duplicateQueryEditor(qe)}
>
<div className="icon-container">
<i className="fa fa-files-o" />
</div>
{t('Duplicate tab')}
</MenuItem>
</SplitButton>
)}
</>
); );
return ( return (
<Tab key={qe.id} title={tabTitle} eventKey={qe.id}> <Tab key={qe.id} title={tabTitle} eventKey={qe.id}>

View File

@ -259,7 +259,7 @@ div.Workspace {
.ddbtn-tab { .ddbtn-tab {
font-size: inherit; font-size: inherit;
font-weight: @font-weight-bold; color: black;
&:active { &:active {
background: none; background: none;

View File

@ -30,6 +30,8 @@ import { Select } from 'src/components/Select';
import { Filters, InternalFilter, SelectOption } from './types'; import { Filters, InternalFilter, SelectOption } from './types';
import { extractInputValue, getDefaultFilterOperator } from './utils'; import { extractInputValue, getDefaultFilterOperator } from './utils';
const styleWidth100p = { width: '100%' };
export const FilterMenu = ({ export const FilterMenu = ({
filters, filters,
internalFilters, internalFilters,
@ -49,7 +51,7 @@ export const FilterMenu = ({
<> <>
<i className="fa fa-filter text-primary" /> <i className="fa fa-filter text-primary" />
{' '} {' '}
{t('Filter List')} {t('Filter')}
</> </>
} }
> >
@ -181,12 +183,13 @@ export const FilterInputs = ({
{internalFilters.length > 0 && ( {internalFilters.length > 0 && (
<> <>
<Row> <Row>
<Col md={10} /> <Col md={11} />
<Col md={2}> <Col md={1}>
<Button <Button
data-test="apply-filters" data-test="apply-filters"
disabled={!!filtersApplied} disabled={!!filtersApplied}
bsStyle="primary" bsStyle="primary"
style={styleWidth100p}
onClick={applyFilters} onClick={applyFilters}
bsSize="small" bsSize="small"
> >

View File

@ -125,11 +125,11 @@ const ListView: FunctionComponent<Props> = ({
{title && filterable && ( {title && filterable && (
<> <>
<Row> <Row>
<Col md={10}> <Col md={11}>
<h2>{t(title)}</h2> <h2>{t(title)}</h2>
</Col> </Col>
{filterable && ( {filterable && (
<Col md={2}> <Col md={1}>
<FilterMenu <FilterMenu
filters={filters} filters={filters}
internalFilters={internalFilters} internalFilters={internalFilters}

View File

@ -0,0 +1,21 @@
/**
* 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

@ -20,8 +20,10 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { ButtonGroup, OverlayTrigger, Tooltip } from 'react-bootstrap'; import { ButtonGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
import classnames from 'classnames'; import classnames from 'classnames';
import { t } from '@superset-ui/translation';
import Button from '../../components/Button'; import Button from '../../components/Button';
import './QueryAndSaveBtns.css';
const propTypes = { const propTypes = {
canAdd: PropTypes.bool.isRequired, canAdd: PropTypes.bool.isRequired,
@ -50,6 +52,7 @@ export default function QueryAndSaveBtns({
}) { }) {
const saveClasses = classnames({ const saveClasses = classnames({
'disabled disabledButton': !canAdd, 'disabled disabledButton': !canAdd,
'save-btn': true,
}); });
let qryButtonStyle = 'default'; let qryButtonStyle = 'default';
@ -61,17 +64,17 @@ export default function QueryAndSaveBtns({
const saveButtonDisabled = errorMessage ? true : loading; const saveButtonDisabled = errorMessage ? true : loading;
const qryOrStopButton = loading ? ( const qryOrStopButton = loading ? (
<Button onClick={onStop} bsStyle="warning"> <Button onClick={onStop} bsStyle="warning" className="save-btn">
<i className="fa fa-stop-circle-o" /> Stop <i className="fa fa-stop-circle-o" /> Stop
</Button> </Button>
) : ( ) : (
<Button <Button
className="query" className="query save-btn"
onClick={onQuery} onClick={onQuery}
bsStyle={qryButtonStyle} bsStyle={qryButtonStyle}
disabled={!!errorMessage} disabled={!!errorMessage}
> >
<i className="fa fa-bolt" /> Run Query <i className="fa fa-bolt" /> {t('Run')}
</Button> </Button>
); );

View File

@ -66,6 +66,10 @@
// Buttons ==================================================================== // Buttons ====================================================================
.btn {
text-transform: uppercase;
}
.btn-default:hover { .btn-default:hover {
color: @gray-dark; color: @gray-dark;
background-color: @gray-bg; background-color: @gray-bg;
@ -277,10 +281,13 @@ table,
.label { .label {
border-radius: @border-radius-normal; border-radius: @border-radius-normal;
padding: 0.3em 0.6em 0.2em;
font-weight: @font-weight-normal;
} }
label { label {
font-weight: @font-weight-normal; font-weight: @font-weight-normal;
font-size: @font-size-s;
} }
// Progress bars ============================================================== // Progress bars ==============================================================
@ -292,7 +299,7 @@ label {
.progress-bar { .progress-bar {
font-size: @font-size-s; font-size: @font-size-s;
line-height: @line-height-tight; line-height: @line-height-tight;
padding-top: 1px; padding-top: 2px;
} }
} }
@ -415,6 +422,7 @@ a.list-group-item {
.nav-tabs > li > a { .nav-tabs > li > a {
border-top: 3px solid transparent; border-top: 3px solid transparent;
color: @text-color;
} }
.nav-tabs > li.active > a, .nav-tabs > li.active > a,

View File

@ -107,8 +107,8 @@
@line-height-small: 1.5; @line-height-small: 1.5;
@border-radius-base: @border-radius-normal; @border-radius-base: @border-radius-normal;
@border-radius-large: 2px; @border-radius-large: 4px;
@border-radius-small: 2px; @border-radius-small: 4px;
// ** Global color for active items (e.g., navs or dropdowns). // ** Global color for active items (e.g., navs or dropdowns).
@component-active-color: @lightest; // superset-var @component-active-color: @lightest; // superset-var
@ -146,12 +146,12 @@
@btn-font-weight: normal; @btn-font-weight: normal;
@btn-primary-color: @lightest; // superset-var @btn-primary-color: @lightest;
@btn-primary-bg: @brand-primary; @btn-primary-bg: @brand-primary;
@btn-primary-border: @brand-primary; @btn-primary-border: @brand-primary;
@btn-default-color: @bs-gray; @btn-default-color: @bs-gray;
@btn-default-bg: @lightest; // superset-var @btn-default-bg: @lightest;
@btn-default-border: @bs-gray-light; @btn-default-border: @bs-gray-light;
@btn-success-color: @btn-primary-color; @btn-success-color: @btn-primary-color;
@ -162,7 +162,7 @@
@btn-info-bg: @brand-info; @btn-info-bg: @brand-info;
@btn-info-border: @btn-info-bg; @btn-info-border: @btn-info-bg;
@btn-warning-color: @btn-default-color; @btn-warning-color: @btn-primary-color;
@btn-warning-bg: @brand-warning; @btn-warning-bg: @brand-warning;
@btn-warning-border: @btn-warning-bg; @btn-warning-border: @btn-warning-bg;

View File

@ -24,8 +24,26 @@
/* component styles. This will allow us to more easily adjust theming */ /* component styles. This will allow us to more easily adjust theming */
/************************************************************************/ /************************************************************************/
@primary-color: #00a699; @primary-color: #20a7c9;
@indicator-color: #44c0ff; @indicator-color: @primary-color;
@brand-primary-dark1: #1a85a0;
@brand-primary-dark2: #156378;
@brand-primary-light1: #79cade;
@brand-primary-light2: #a5dae9;
@brand-primary-light3: #d2edf4;
@brand-primary-light4: #e9f6f9;
@brand-primary-light5: #f3f8fa;
@brand-secondary: #444e7c;
@brand-secondary-dark1: #363e63;
@brand-secondary-dark2: #282e4a;
@brand-secondary-dark3: #1b1f31;
@brand-secondary-light1: #8e94b0;
@brand-secondary-light2: #b4b8ca;
@brand-secondary-light3: #d9dbe4;
@brand-secondary-light4: #eceef2;
@brand-secondary-light5: #f5f5f8;
@almost-black: #263238; @almost-black: #263238;
@gray-dark: #484848; @gray-dark: #484848;
@ -38,18 +56,14 @@
@darkest: #000000; @darkest: #000000;
/**************************** text-specific *****************************/ /**************************** text-specific *****************************/
@link: @brand-primary; @link: #1985a0;
@link-hover: darken(@link, @colorstop-one); @link-hover: darken(@link, @colorstop-one);
/***************************** status colors ****************************/ /***************************** status colors ****************************/
@success: #4ac15f; @success: #5ac189;
@info: lighten(#2ab7ca, 15%); @info: #66bcfe;
@warning: mix( @warning: #ff7f44;
#fed766, @danger: #e04355;
#ffab00,
50%
); // mix of old superset warning color and cosmo warning color. Compromise!
@danger: #fe4a49;
/* general component effects */ /* general component effects */
@shadow-highlight: @primary-color; @shadow-highlight: @primary-color;
@ -185,7 +199,7 @@
/* BORDER RADII */ /* BORDER RADII */
/* Standard border-radius settings */ /* Standard border-radius settings */
/************************************************************************/ /************************************************************************/
@border-radius-normal: 2px; @border-radius-normal: 4px;
@border-radius-large: (@border-radius-normal * 2); @border-radius-large: (@border-radius-normal * 2);
/************************************************************************/ /************************************************************************/

View File

@ -445,7 +445,7 @@ table.table-no-hover tr:hover {
} }
.list-add-action .btn.btn-sm { .list-add-action .btn.btn-sm {
padding: 5px 6px; padding: 6px 6px;
font-size: @font-size-xs; font-size: @font-size-xs;
line-height: 2px; line-height: 2px;
border-radius: 50%; border-radius: 50%;