feat: minor reorder SQL Lab Tab controls (#10257)

This commit is contained in:
Grace Guo 2020-07-08 16:21:47 -07:00 committed by GitHub
parent baeacc3c56
commit 6690963ec2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 64 deletions

View File

@ -40,10 +40,12 @@ describe('SqlLab query tabs', () => {
const initialTabCount = tabListA.length; const initialTabCount = tabListA.length;
// open the tab dropdown to remove // open the tab dropdown to remove
cy.get('.SqlEditorTabs > ul > li .dropdown-toggle').click(); cy.get('.SqlEditorTabs > ul > li .dropdown-toggle').click({
force: true,
});
// first item is close // first item is close
cy.get('.SqlEditorTabs .close-btn a').click(); cy.get('.SqlEditorTabs .ddbtn-tab .close').first().click();
cy.get('.SqlEditorTabs > ul > li').should( cy.get('.SqlEditorTabs > ul > li').should(
'have.length', 'have.length',

View File

@ -36,18 +36,4 @@ describe('TabStatusIcon', () => {
expect(wrapper.find('div.circle')).toHaveLength(1); expect(wrapper.find('div.circle')).toHaveLength(1);
expect(wrapper.text()).toBe(''); expect(wrapper.text()).toBe('');
}); });
it('renders a circle with an x when hovered', () => {
const { wrapper } = setup();
wrapper.simulate('mouseOver');
expect(wrapper.find('div.circle')).toHaveLength(1);
expect(wrapper.text()).toBe('×');
});
it('calls onClose from props when clicked', () => {
const { wrapper, onClose } = setup();
wrapper.simulate('click');
// eslint-disable-next-line no-unused-expressions
expect(onClose.calledOnce).toBe(true);
});
}); });

View File

@ -19,42 +19,10 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const propTypes = { export default function TabStatusIcon(props) {
onClose: PropTypes.func.isRequired, return <div className={'circle ' + props.tabState} />;
tabState: PropTypes.string.isRequired,
};
class TabStatusIcon extends React.Component {
constructor(props) {
super(props);
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseOut = this.onMouseOut.bind(this);
this.state = { isHovered: false };
}
onMouseOver() {
this.setState({ isHovered: true });
}
onMouseOut() {
this.setState({ isHovered: false });
}
render() {
return (
<span
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
onClick={this.props.onClose}
>
<div className={'circle ' + this.props.tabState}>
{this.state.isHovered ? '×' : null}
</div>
</span>
);
}
} }
TabStatusIcon.propTypes = propTypes; TabStatusIcon.propTypes = {
export default TabStatusIcon; tabState: PropTypes.string.isRequired,
};

View File

@ -18,7 +18,7 @@
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { MenuItem, SplitButton, Tab, Tabs } from 'react-bootstrap'; import { MenuItem, DropdownButton, Tab, Tabs } from 'react-bootstrap';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import URI from 'urijs'; import URI from 'urijs';
@ -288,22 +288,20 @@ class TabbedSqlEditors extends React.PureComponent {
const title = ( const title = (
<> <>
<TabStatusIcon {qe.title} <TabStatusIcon tabState={state} />{' '}
onClose={() => this.removeQueryEditor(qe)} <span className="close" onClick={() => this.removeQueryEditor(qe)}>
tabState={state} {'×'}
/>{' '} </span>
{qe.title}{' '}
</> </>
); );
const tabTitle = ( const tabTitle = (
<> <>
<span className="ddbtn-tab">{title}</span>
{isSelected && ( {isSelected && (
<SplitButton <DropdownButton
bsSize="small" bsSize="small"
id={'ddbtn-tab-' + i} id={'ddbtn-tab-' + i}
className="ddbtn-tab" title={' '}
title="&nbsp;" noCaret
> >
<MenuItem <MenuItem
className="close-btn" className="close-btn"
@ -347,8 +345,9 @@ class TabbedSqlEditors extends React.PureComponent {
</div> </div>
{t('Duplicate tab')} {t('Duplicate tab')}
</MenuItem> </MenuItem>
</SplitButton> </DropdownButton>
)} )}
<span className="ddbtn-tab">{title}</span>
</> </>
); );
return ( return (

View File

@ -261,9 +261,56 @@ div.Workspace {
} }
} }
.dropdown.btn-group.btn-group-sm {
width: 3px;
height: 3px;
border-radius: 1.5px;
background: #bababa;
margin-right: 8px;
font-weight: @font-weight-normal;
display: inline-flex;
&:hover {
background-color: @primary-color;
&:before,
&:after {
background-color: @primary-color;
}
}
&:before,
&:after {
position: absolute;
content: ' ';
width: 3px;
height: 3px;
border-radius: 1.5px;
background-color: #bababa;
}
&:before {
transform: translateY(-5px);
}
&:after {
transform: translateY(5px);
}
}
ul.dropdown-menu {
margin-top: 10px;
}
.dropdown-toggle { .dropdown-toggle {
padding-top: 2px; padding-top: 2px;
} }
.close {
opacity: 1;
color: @almost-black;
position: relative;
top: -2px;
right: -4px;
}
} }
.SqlEditor { .SqlEditor {
@ -462,6 +509,8 @@ a.Link {
padding: 0; padding: 0;
border: none; border: none;
background: none; background: none;
position: relative;
top: 2px;
&:focus { &:focus {
outline: 0; outline: 0;