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: update sql toolbar styling #12164

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
123 changes: 79 additions & 44 deletions superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,75 +17,110 @@
* under the License.
*/
import React from 'react';
import { t } from '@superset-ui/core';
import { t, styled, supersetTheme } from '@superset-ui/core';

import { Dropdown, Menu } from 'src/common/components';
import { Menu } from 'src/common/components';
import Button, { ButtonProps } from 'src/components/Button';
import Icon from 'src/components/Icon';

const NO_OP = () => undefined;
import { DropdownButton, DropdownProps } from 'src/common/components/Dropdown';

interface Props {
allowAsync: boolean;
dbId?: number;
queryState?: string;
runQuery: (c?: boolean) => void;
selectedText?: string;
stopQuery: () => void;
sql: string;
overlayCreateAsMenu: typeof Menu;
overlayCreateAsMenu: typeof Menu | null;
}

type QueryButtonProps = DropdownProps | ButtonProps;

const buildText = (
shouldShowStopButton: boolean,
selectedText: string | undefined,
): string | JSX.Element => {
if (shouldShowStopButton) {
return (
<>
<i className="fa fa-stop" /> {t('Stop')}
</>
);
}
if (selectedText) {
return t('Run Selection');
}
return t('Run');
};

const onClick = (
shouldShowStopButton: boolean,
allowAsync: boolean,
runQuery: (c?: boolean) => void = () => undefined,
stopQuery = () => {},
): void => {
if (shouldShowStopButton) return stopQuery();
if (allowAsync) {
return runQuery(true);
}
return runQuery(false);
};

const StyledButton = styled.span`
button {
line-height: 13px;
&:last-of-type {
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
}
}
`;

const RunQueryActionButton = ({
allowAsync = false,
dbId,
queryState,
runQuery = NO_OP,
selectedText,
stopQuery = NO_OP,
sql = '',
overlayCreateAsMenu,
runQuery,
stopQuery,
}: Props) => {
const runBtnText = selectedText ? t('Run Selection') : t('Run');
const btnStyle = selectedText ? 'warning' : 'primary';
const shouldShowStopBtn =
!!queryState && ['running', 'pending'].indexOf(queryState) > -1;

if (shouldShowStopBtn) {
return (
<Dropdown.Button
onClick={stopQuery}
icon={<Icon color="#00000" name="caret-down" />}
type={btnStyle}
overlay={overlayCreateAsMenu}
disabled={!sql.trim()}
>
<i className="fa fa-stop" /> {t('Stop')}
</Dropdown.Button>
);
}
if (allowAsync) {
return (
<Dropdown.Button
onClick={() => runQuery(true)}
icon={<Icon color="#00000" name="caret-down" />}
type={btnStyle}
overlay={overlayCreateAsMenu}
const ButtonComponent: React.FC<QueryButtonProps> = overlayCreateAsMenu
? (DropdownButton as React.FC)
: Button;

return (
<StyledButton>
<ButtonComponent
onClick={() =>
onClick(shouldShowStopBtn, allowAsync, runQuery, stopQuery)
}
disabled={!sql.trim()}
buttonSize="small"
tooltip={
shouldShowStopBtn
? t('Stop running (Ctrl + x)')
: t('Run query (Ctrl + Return)')
}
cta
{...(overlayCreateAsMenu
? {
overlay: overlayCreateAsMenu,
icon: (
<Icon
color={supersetTheme.colors.grayscale.light5}
name="caret-down"
/>
),
}
: { buttonStyle: btnStyle })}
>
<i className="fa fa-bolt" /> {runBtnText}
</Dropdown.Button>
);
}
return (
<Dropdown.Button
onClick={() => runQuery(false)}
icon={<Icon color="#00000" name="caret-down" />}
type={btnStyle}
overlay={overlayCreateAsMenu}
disabled={!sql.trim()}
>
<i className="fa fa-refresh" /> {runBtnText}
</Dropdown.Button>
{buildText(shouldShowStopBtn, selectedText)}
</ButtonComponent>
</StyledButton>
);
};

Expand Down
93 changes: 62 additions & 31 deletions superset-frontend/src/SqlLab/components/SqlEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { bindActionCreators } from 'redux';
import PropTypes from 'prop-types';
import { Form } from 'react-bootstrap';
import Split from 'react-split';
import { t, styled } from '@superset-ui/core';
import { t, styled, supersetTheme } from '@superset-ui/core';
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';
import StyledModal from 'src/common/components/Modal';
Expand Down Expand Up @@ -88,8 +88,46 @@ const WINDOW_RESIZE_THROTTLE_MS = 100;

const LimitSelectStyled = styled.span`
.ant-dropdown-trigger {
align-items: center;
color: black;
display: flex;
font-size: 12px;
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
text-decoration: none;
span {
display: inline-block;
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
&:last-of-type: {
margin-right: ${({ theme }) => theme.gridUnit * 4}px;
}
}
}
`;

const StyledToolbar = styled.div`
padding: 10px 10px 5px 10px;
background-color: @lightest;
display: flex;
justify-content: space-between;
border: 1px solid ${supersetTheme.colors.grayscale.light2};
border-top: 0;

form {
margin-block-end: 0;
}

.leftItems form,
.rightItems {
display: flex;
align-items: center;
& > span {
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
display: inline-block;

&:last-child {
margin-right: 0;
}
}
}
`;

Expand All @@ -100,7 +138,7 @@ const propTypes = {
tables: PropTypes.array.isRequired,
editorQueries: PropTypes.array.isRequired,
dataPreviewQueries: PropTypes.array.isRequired,
queryEditorId: PropTypes.number.isRequired,
queryEditorId: PropTypes.string.isRequired,
hideLeftBar: PropTypes.bool,
defaultQueryLimit: PropTypes.number.isRequired,
maxRow: PropTypes.number.isRequired,
Expand Down Expand Up @@ -534,10 +572,8 @@ class SqlEditor extends React.PureComponent {
}

// eslint-disable-next-line camelcase
const {
allow_ctas: allowCTAS,
allow_cvas: allowCVAS,
} = this.props.database;
const { allow_ctas: allowCTAS, allow_cvas: allowCVAS } =
this.props.database || {};

const showMenu = allowCTAS || allowCVAS;
const runMenuBtn = (
Expand Down Expand Up @@ -572,7 +608,7 @@ class SqlEditor extends React.PureComponent {
);

return (
<div className="sql-toolbar" id="js-sql-toolbar">
<StyledToolbar className="sql-toolbar" id="js-sql-toolbar">
<div className="leftItems">
<Form inline>
<span>
Expand All @@ -582,13 +618,12 @@ class SqlEditor extends React.PureComponent {
? this.props.database.allow_run_async
: false
}
dbId={qe.dbId}
queryState={this.props.latestQuery?.state}
runQuery={this.runQuery}
selectedText={qe.selectedText}
stopQuery={this.stopQuery}
sql={this.state.sql}
overlayCreateAsMenu={showMenu ? runMenuBtn : <></>}
overlayCreateAsMenu={showMenu ? runMenuBtn : null}
/>
</span>
{isFeatureEnabled(FeatureFlag.ESTIMATE_QUERY_COST) &&
Expand All @@ -607,31 +642,35 @@ class SqlEditor extends React.PureComponent {
</span>
)}
{limitWarning}
{this.props.latestQuery && (
<Timer
startTime={this.props.latestQuery.startDttm}
endTime={this.props.latestQuery.endDttm}
state={STATE_BSSTYLE_MAP[this.props.latestQuery.state]}
isRunning={this.props.latestQuery.state === 'running'}
/>
)}
<span>
<LimitSelectStyled>
<Dropdown overlay={this.renderQueryLimit()}>
<a onClick={e => e.preventDefault()}>
<b>LIMIT:</b>{' '}
{this.props.queryEditor.queryLimit !== undefined
? this.props.queryEditor.queryLimit
: this.props.defaultQueryLimit}
<span>LIMIT:</span>
<span>
{(
this.props.queryEditor.queryLimit ||
this.props.defaultQueryLimit
).toLocaleString()}
</span>
<Icon name="triangle-down" />
</a>
</Dropdown>
</LimitSelectStyled>
</span>
{this.props.latestQuery && (
<Timer
startTime={this.props.latestQuery.startDttm}
endTime={this.props.latestQuery.endDttm}
state={STATE_BSSTYLE_MAP[this.props.latestQuery.state]}
isRunning={this.props.latestQuery.state === 'running'}
/>
)}
</Form>
</div>
<div
className="rightItems"
style={{ display: 'flex', 'align-items': 'center' }}
style={{ display: 'flex', alignItems: 'center' }}
>
<span>
<SaveQuery
Expand All @@ -646,19 +685,11 @@ class SqlEditor extends React.PureComponent {
<ShareSqlLabQuery queryEditor={qe} />
</span>
{limitWarning}
{this.props.latestQuery && (
<Timer
startTime={this.props.latestQuery.startDttm}
endTime={this.props.latestQuery.endDttm}
state={STATE_BSSTYLE_MAP[this.props.latestQuery.state]}
isRunning={this.props.latestQuery.state === 'running'}
/>
)}
<Dropdown overlay={this.renderDropdown()} arrow>
<Icon name="more-horiz" />
</Dropdown>
</div>
</div>
</StyledToolbar>
);
}

Expand Down
27 changes: 0 additions & 27 deletions superset-frontend/src/SqlLab/main.less
Original file line number Diff line number Diff line change
Expand Up @@ -132,33 +132,6 @@ div.Workspace {
padding-top: 10px;
}

.sql-toolbar {
padding: 10px 10px 5px 10px;
background-color: @lightest;
display: flex;
justify-content: space-between;
border: 1px solid @gray-light;
border-top: 0;

form {
margin-block-end: 0;
}

.leftItems form,
.rightItems {
& > span {
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;

&:last-child {
margin-right: 0;
font-feature-settings: 'kern' 1, 'tnum' 1;
}
}
}
}

.no-shadow {
box-shadow: none;
background-color: transparent;
Expand Down
Loading