chore: Migrate .less styles to Emotion (#22474)

This commit is contained in:
Kamil Gabryjelski
2023-01-19 09:17:10 +01:00
committed by GitHub
parent 5026da50e1
commit 39c96d0568
61 changed files with 1665 additions and 2414 deletions

View File

@@ -42,9 +42,9 @@ import {
import { BYTES_PER_CHAR, KB_STORAGE } from './constants';
import setupApp from '../setup/setupApp';
import './main.less';
import '../assets/stylesheets/reactable-pagination.less';
import { theme } from '../preamble';
import { SqlLabGlobalStyles } from './SqlLabGlobalStyles';
setupApp();
setupExtensions();
@@ -141,6 +141,7 @@ const Application = () => (
<Provider store={store}>
<ThemeProvider theme={theme}>
<GlobalStyles />
<SqlLabGlobalStyles />
<App />
</ThemeProvider>
</Provider>

View File

@@ -0,0 +1,36 @@
/**
* 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 { Global } from '@emotion/react';
import { css } from '@superset-ui/core';
export const SqlLabGlobalStyles = () => (
<Global
styles={theme => css`
body {
min-height: max(
100vh,
${theme.gridUnit * 125}px
); // Set a min height so the gutter is always visible when resizing
overflow: hidden;
}
`}
/>
);

View File

@@ -18,6 +18,8 @@
*/
import React, { useState, useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { css, styled } from '@superset-ui/core';
import { usePrevious } from 'src/hooks/usePrevious';
import { areArraysShallowEqual } from 'src/reduxUtils';
import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
@@ -57,6 +59,28 @@ type AceEditorWrapperProps = {
hotkeys: HotKey[];
};
const StyledAceEditor = styled(AceEditor)`
${({ theme }) => css`
&& {
// double class is better than !important
border: 1px solid ${theme.colors.grayscale.light2};
font-feature-settings: 'liga' off, 'calt' off;
// Fira Code causes problem with Ace under Firefox
font-family: 'Menlo', 'Consolas', 'Courier New', 'Ubuntu Mono',
'source-code-pro', 'Lucida Console', monospace;
&.ace_autocomplete {
// Use !important because Ace Editor applies extra CSS at the last second
// when opening the autocomplete.
width: ${theme.gridUnit * 130}px !important;
}
.ace_scroller {
background-color: ${theme.colors.grayscale.light4};
}
}
`}
`;
const AceEditorWrapper = ({
autocomplete,
onBlur = () => {},
@@ -258,7 +282,7 @@ const AceEditorWrapper = ({
};
return (
<AceEditor
<StyledAceEditor
keywords={words}
onLoad={onEditorLoad}
onBlur={onBlurSql}

View File

@@ -20,7 +20,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { t } from '@superset-ui/core';
import { css, styled, t } from '@superset-ui/core';
import throttle from 'lodash/throttle';
import ToastContainer from 'src/components/MessageToasts/ToastContainer';
import {
@@ -32,6 +32,69 @@ import * as Actions from 'src/SqlLab/actions/sqlLab';
import TabbedSqlEditors from '../TabbedSqlEditors';
import QueryAutoRefresh from '../QueryAutoRefresh';
const SqlLabStyles = styled.div`
${({ theme }) => css`
&.SqlLab {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 0 ${theme.gridUnit * 2}px;
pre {
padding: 0 !important;
margin: 0;
border: none;
font-size: ${theme.typography.sizes.s}px;
background: transparent !important;
}
.north-pane {
display: flex;
flex-direction: column;
}
.ace_editor {
flex-grow: 1;
}
.ace_content {
height: 100%;
}
.ant-tabs-content-holder {
/* This is needed for Safari */
height: 100%;
}
.ant-tabs-content {
height: 100%;
position: relative;
background-color: ${theme.colors.grayscale.light5};
overflow-x: auto;
overflow-y: auto;
> .ant-tabs-tabpane {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
.ResultsModal .ant-modal-body {
min-height: ${theme.gridUnit * 140}px;
}
.ant-modal-body {
overflow: auto;
}
}
`};
`;
class App extends React.PureComponent {
constructor(props) {
super(props);
@@ -99,7 +162,7 @@ class App extends React.PureComponent {
return window.location.replace('/superset/sqllab/history/');
}
return (
<div className="App SqlLab">
<SqlLabStyles className="App SqlLab">
<QueryAutoRefresh
queries={queries}
refreshQueries={actions?.refreshQueries}
@@ -107,7 +170,7 @@ class App extends React.PureComponent {
/>
<TabbedSqlEditors />
<ToastContainer />
</div>
</SqlLabStyles>
);
}
}

View File

@@ -18,7 +18,7 @@
*/
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { t } from '@superset-ui/core';
import { css, styled, t } from '@superset-ui/core';
import Alert from 'src/components/Alert';
import TableView from 'src/components/TableView';
@@ -36,6 +36,12 @@ export interface EstimateQueryCostButtonProps {
disabled?: boolean;
}
const CostEstimateModalStyles = styled.div`
${({ theme }) => css`
font-size: ${theme.typography.sizes.s};
`}
`;
const EstimateQueryCostButton = ({
getEstimate,
queryEditorId,
@@ -76,13 +82,14 @@ const EstimateQueryCostButton = ({
}
if (queryCostEstimate?.completed) {
return (
<TableView
columns={columns}
data={tableData}
withPagination={false}
emptyWrapperType={EmptyWrapperType.Small}
className="cost-estimate"
/>
<CostEstimateModalStyles>
<TableView
columns={columns}
data={tableData}
withPagination={false}
emptyWrapperType={EmptyWrapperType.Small}
/>
</CostEstimateModalStyles>
);
}
return <Loading position="normal" />;

View File

@@ -17,8 +17,7 @@
* under the License.
*/
import React from 'react';
import { shallow } from 'enzyme';
import { styledMount as mount } from 'spec/helpers/theming';
import Label from 'src/components/Label';
import QueryStateLabel from 'src/SqlLab/components/QueryStateLabel';
@@ -34,7 +33,7 @@ describe('SavedQuery', () => {
);
});
it('has an Overlay and a Popover', () => {
const wrapper = shallow(<QueryStateLabel {...mockedProps} />);
const wrapper = mount(<QueryStateLabel {...mockedProps} />);
expect(wrapper.find(Label)).toExist();
});
});

View File

@@ -19,16 +19,18 @@
import React from 'react';
import Label from 'src/components/Label';
import { STATE_TYPE_MAP } from 'src/SqlLab/constants';
import { Query } from '@superset-ui/core';
import { styled, Query } from '@superset-ui/core';
interface QueryStateLabelProps {
query: Query;
}
const StyledLabel = styled(Label)`
margin-right: ${({ theme }) => theme.gridUnit}px;
`;
export default function QueryStateLabel({ query }: QueryStateLabelProps) {
return (
<Label className="m-r-3" type={STATE_TYPE_MAP[query.state]}>
{query.state}
</Label>
<StyledLabel type={STATE_TYPE_MAP[query.state]}>{query.state}</StyledLabel>
);
}

View File

@@ -22,7 +22,13 @@ import ButtonGroup from 'src/components/ButtonGroup';
import Alert from 'src/components/Alert';
import Button from 'src/components/Button';
import shortid from 'shortid';
import { QueryResponse, QueryState, styled, t } from '@superset-ui/core';
import {
QueryResponse,
QueryState,
styled,
t,
useTheme,
} from '@superset-ui/core';
import { usePrevious } from 'src/hooks/usePrevious';
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import {
@@ -133,6 +139,7 @@ const ResultSet = ({
user,
defaultQueryLimit,
}: ResultSetProps) => {
const theme = useTheme();
const [searchText, setSearchText] = useState('');
const [cachedData, setCachedData] = useState<Record<string, unknown>[]>([]);
const [showSaveDatasetModal, setShowSaveDatasetModal] = useState(false);
@@ -449,7 +456,7 @@ const ResultSet = ({
<ButtonGroup>
<Button
buttonSize="small"
className="m-r-5"
css={{ marginRight: theme.gridUnit }}
onClick={() => popSelectStar(tempSchema, tempTable)}
>
{t('Query in a new tab')}

View File

@@ -23,7 +23,7 @@ import { CSSTransition } from 'react-transition-group';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import Split from 'react-split';
import { t, styled, useTheme } from '@superset-ui/core';
import { css, t, styled, useTheme } from '@superset-ui/core';
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';
import Modal from 'src/components/Modal';
@@ -132,6 +132,62 @@ const StyledSidebar = styled.div`
hide ? 'transparent' : theme.colors.grayscale.light2};
`;
const StyledSqlEditor = styled.div`
${({ theme }) => css`
display: flex;
flex-direction: row;
height: 100%;
.schemaPane {
transition: transform ${theme.transitionTiming}s ease-in-out;
}
.queryPane {
flex: 1 1 auto;
padding: ${theme.gridUnit * 2}px;
overflow-y: auto;
overflow-x: scroll;
}
.schemaPane-enter-done,
.schemaPane-exit {
transform: translateX(0);
z-index: 7;
}
.schemaPane-exit-active {
transform: translateX(-120%);
}
.schemaPane-enter-active {
transform: translateX(0);
max-width: ${theme.gridUnit * 75}px;
}
.schemaPane-enter,
.schemaPane-exit-done {
max-width: 0;
transform: translateX(-120%);
overflow: hidden;
}
.schemaPane-exit-done + .queryPane {
margin-left: 0;
}
.gutter {
border-top: 1px solid ${theme.colors.grayscale.light2};
border-bottom: 1px solid ${theme.colors.grayscale.light2};
width: 3%;
margin: ${theme.gridUnit}px 47%;
}
.gutter.gutter-vertical {
cursor: row-resize;
}
`}
`;
const propTypes = {
tables: PropTypes.array.isRequired,
queryEditor: PropTypes.object.isRequired,
@@ -636,7 +692,7 @@ const SqlEditor = ({
? 'schemaPane-exit-done'
: 'schemaPane-enter-done';
return (
<div ref={sqlEditorRef} className="SqlEditor">
<StyledSqlEditor ref={sqlEditorRef} className="SqlEditor">
<CSSTransition classNames="schemaPane" in={!hideLeftBar} timeout={300}>
<ResizableSidebar
id={`sqllab:${queryEditor.id}`}
@@ -704,7 +760,7 @@ const SqlEditor = ({
<span>{t('Name')}</span>
<Input placeholder={createModalPlaceHolder} onChange={ctasChanged} />
</Modal>
</div>
</StyledSqlEditor>
);
};

View File

@@ -89,12 +89,25 @@ const collapseStyles = (theme: SupersetTheme) => css`
.ant-collapse-arrow {
top: ${theme.gridUnit * 2}px !important;
color: ${theme.colors.primary.dark1} !important;
&: hover {
&:hover {
color: ${theme.colors.primary.dark2} !important;
}
}
`;
const LeftBarStyles = styled.div`
${({ theme }) => css`
height: 100%;
display: flex;
flex-direction: column;
.divider {
border-bottom: 1px solid ${theme.colors.grayscale.light4};
margin: ${theme.gridUnit * 4}px 0;
}
`}
`;
const SqlEditorLeftBar = ({
database,
queryEditorId,
@@ -228,7 +241,7 @@ const SqlEditorLeftBar = ({
}, []);
return (
<div data-test="sql-editor-left-bar" className="SqlEditorLeftBar">
<LeftBarStyles data-test="sql-editor-left-bar">
<TableSelectorMultiple
onEmptyResults={onEmptyResults}
emptyState={emptyStateComponent(emptyResultsWithSearch)}
@@ -276,7 +289,7 @@ const SqlEditorLeftBar = ({
<i className="fa fa-bomb" /> {t('Reset state')}
</Button>
)}
</div>
</LeftBarStyles>
);
};

View File

@@ -41,6 +41,12 @@ const TabTitle = styled.span`
text-transform: none;
`;
const IconContainer = styled.div`
display: inline-block;
width: ${({ theme }) => theme.gridUnit * 8}px;
text-align: center;
`;
interface Props {
queryEditor: QueryEditor;
}
@@ -91,9 +97,9 @@ const SqlEditorTabHeader: React.FC<Props> = ({ queryEditor }) => {
onClick={() => actions.removeQueryEditor(qe)}
data-test="close-tab-menu-option"
>
<div className="icon-container">
<IconContainer>
<i className="fa fa-close" />
</div>
</IconContainer>
{t('Close tab')}
</Menu.Item>
<Menu.Item
@@ -101,9 +107,9 @@ const SqlEditorTabHeader: React.FC<Props> = ({ queryEditor }) => {
onClick={renameTab}
data-test="rename-tab-menu-option"
>
<div className="icon-container">
<IconContainer>
<i className="fa fa-i-cursor" />
</div>
</IconContainer>
{t('Rename tab')}
</Menu.Item>
<Menu.Item
@@ -111,9 +117,9 @@ const SqlEditorTabHeader: React.FC<Props> = ({ queryEditor }) => {
onClick={() => actions.toggleLeftBar(qe)}
data-test="toggle-menu-option"
>
<div className="icon-container">
<IconContainer>
<i className="fa fa-cogs" />
</div>
</IconContainer>
{qe.hideLeftBar ? t('Expand tool bar') : t('Hide tool bar')}
</Menu.Item>
<Menu.Item
@@ -121,9 +127,9 @@ const SqlEditorTabHeader: React.FC<Props> = ({ queryEditor }) => {
onClick={() => actions.removeAllOtherQueryEditors(qe)}
data-test="close-all-other-menu-option"
>
<div className="icon-container">
<IconContainer>
<i className="fa fa-times-circle-o" />
</div>
</IconContainer>
{t('Close all other tabs')}
</Menu.Item>
<Menu.Item
@@ -131,9 +137,9 @@ const SqlEditorTabHeader: React.FC<Props> = ({ queryEditor }) => {
onClick={() => actions.cloneQueryToNewTab(qe, false)}
data-test="clone-tab-menu-option"
>
<div className="icon-container">
<IconContainer>
<i className="fa fa-files-o" />
</div>
</IconContainer>
{t('Duplicate tab')}
</Menu.Item>
</Menu>

View File

@@ -17,13 +17,42 @@
* under the License.
*/
import React from 'react';
import { QueryState, styled } from '@superset-ui/core';
import { css, QueryState, styled } from '@superset-ui/core';
import Icons, { IconType } from 'src/components/Icons';
const IconContainer = styled.span`
position: absolute;
top: -7px;
left: 0px;
top: -6px;
left: 1px;
`;
const Circle = styled.div`
${({ theme }) => css`
border-radius: 50%;
width: ${theme.gridUnit * 3}px;
height: ${theme.gridUnit * 3}px;
display: inline-block;
background-color: ${theme.colors.grayscale.light2};
text-align: center;
vertical-align: middle;
font-size: ${theme.typography.sizes.m}px;
font-weight: ${theme.typography.weights.bold};
color: ${theme.colors.grayscale.light5};
position: relative;
&.running {
background-color: ${theme.colors.info.base};
}
&.success {
background-color: ${theme.colors.success.base};
}
&.failed {
background-color: ${theme.colors.error.base};
}
`}
`;
interface TabStatusIconProps {
@@ -38,12 +67,12 @@ const STATE_ICONS: Record<string, React.FC<IconType>> = {
export default function TabStatusIcon({ tabState }: TabStatusIconProps) {
const StatusIcon = STATE_ICONS[tabState];
return (
<div className={`circle ${tabState}`}>
<Circle className={`circle ${tabState}`}>
{StatusIcon && (
<IconContainer>
<StatusIcon iconSize="xs" />
</IconContainer>
)}
</div>
</Circle>
);
}

View File

@@ -212,9 +212,9 @@ describe('TabbedSqlEditors', () => {
});
it('should disable new tab when offline', () => {
wrapper = getWrapper();
expect(wrapper.find(EditableTabs).props().hideAdd).toBe(false);
expect(wrapper.find('#a11y-query-editor-tabs').props().hideAdd).toBe(false);
wrapper.setProps({ offline: true });
expect(wrapper.find(EditableTabs).props().hideAdd).toBe(true);
expect(wrapper.find('#a11y-query-editor-tabs').props().hideAdd).toBe(true);
});
it('should have an empty state when query editors is empty', () => {
wrapper = getWrapper();

View File

@@ -54,6 +54,12 @@ const defaultProps = {
scheduleQueryWarning: null,
};
const StyledEditableTabs = styled(EditableTabs)`
height: 100%;
display: flex;
flex-direction: column;
`;
const StyledTab = styled.span`
line-height: 24px;
`;
@@ -303,7 +309,7 @@ class TabbedSqlEditors extends React.PureComponent {
);
return (
<EditableTabs
<StyledEditableTabs
destroyInactiveTabPane
activeKey={this.props.tabHistory[this.props.tabHistory.length - 1]}
id="a11y-query-editor-tabs"
@@ -331,7 +337,7 @@ class TabbedSqlEditors extends React.PureComponent {
>
{editors}
{noQueryEditors && emptyTabState}
</EditableTabs>
</StyledEditableTabs>
);
}
}

View File

@@ -21,7 +21,7 @@ import { useDispatch } from 'react-redux';
import Collapse from 'src/components/Collapse';
import Card from 'src/components/Card';
import ButtonGroup from 'src/components/ButtonGroup';
import { t, styled } from '@superset-ui/core';
import { css, t, styled } from '@superset-ui/core';
import { debounce } from 'lodash';
import { removeDataPreview, removeTables } from 'src/SqlLab/actions/sqlLab';
@@ -61,7 +61,7 @@ export interface TableElementProps {
const StyledSpan = styled.span`
color: ${({ theme }) => theme.colors.primary.dark1};
&: hover {
&:hover {
color: ${({ theme }) => theme.colors.primary.dark2};
}
cursor: pointer;
@@ -72,6 +72,39 @@ const Fade = styled.div`
opacity: ${(props: { hovered: boolean }) => (props.hovered ? 1 : 0)};
`;
const StyledCollapsePanel = styled(Collapse.Panel)`
${({ theme }) => css`
& {
.ws-el-controls {
margin-right: ${-theme.gridUnit}px;
display: flex;
}
.header-container {
display: flex;
flex: 1;
align-items: center;
width: 100%;
.table-name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: ${theme.typography.sizes.l}px;
flex: 1;
}
.header-right-side {
margin-left: auto;
display: flex;
align-items: center;
margin-right: ${theme.gridUnit * 8}px;
}
}
}
`}
`;
const TableElement = ({ table, ...props }: TableElementProps) => {
const dispatch = useDispatch();
@@ -287,7 +320,7 @@ const TableElement = ({ table, ...props }: TableElementProps) => {
};
return (
<Collapse.Panel
<StyledCollapsePanel
{...props}
key={table.id}
header={renderHeader()}
@@ -295,7 +328,7 @@ const TableElement = ({ table, ...props }: TableElementProps) => {
forceRender
>
{renderBody()}
</Collapse.Panel>
</StyledCollapsePanel>
);
};

View File

@@ -1,491 +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.
*/
@import '../assets/stylesheets/less/variables.less';
body {
min-height: ~'max(100vh, 500px)'; // Set a min height so the gutter is always visible when resizing
overflow: hidden;
}
.inlineBlock {
display: inline-block;
}
.valignTop {
vertical-align: top;
}
.inline {
display: inline;
}
.nopadding {
padding: 0px;
}
.pane-cell {
padding: 10px;
overflow: auto;
width: 100%;
height: 100%;
}
.ant-tabs-content-holder {
/* This is needed for Safari */
height: 100%;
}
.ant-tabs-content {
height: 100%;
position: relative;
background-color: @lightest;
overflow-x: auto;
overflow-y: auto;
> .ant-tabs-tabpane {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
.Workspace .btn-sm {
box-shadow: 1px 1px 2px fade(@darkest, @opacity-light);
margin-top: 2px;
padding: 4px;
}
.Workspace hr {
margin-top: 10px;
margin-bottom: 10px;
}
div.Workspace {
height: 100%;
margin: 0px;
}
.padded {
padding: 10px;
}
.p-t-10 {
padding-top: 10px;
}
.p-t-5 {
padding-top: 5px;
}
.m-r-5 {
margin-right: 5px;
}
.m-r-3 {
margin-right: 3px;
}
.m-l-1 {
margin-left: 1px;
}
.m-l-2 {
margin-left: 2px;
}
.m-r-10 {
margin-right: 10px;
}
.m-l-10 {
margin-left: 10px;
}
.m-l-5 {
margin-left: 5px;
}
.m-b-10 {
margin-bottom: 10px;
}
.m-t-5 {
margin-top: 5px;
}
.m-t-10 {
margin-top: 10px;
}
.p-t-10 {
padding-top: 10px;
}
.no-shadow {
box-shadow: none;
background-color: transparent;
}
.pane-west {
height: 100%;
overflow: auto;
}
.circle {
@circle-diameter: 10px;
border-radius: (@circle-diameter / 2);
width: @circle-diameter;
height: @circle-diameter;
display: inline-block;
background-color: @gray-light;
text-align: center;
vertical-align: middle;
font-size: @font-size-m;
font-weight: @font-weight-bold;
color: @lightest;
position: relative;
}
.running {
background-color: @info;
}
.success {
background-color: @success;
}
.failed {
background-color: @danger;
}
.handle {
cursor: move;
}
#a11y-query-editor-tabs {
height: 100%;
display: flex;
flex-direction: column;
}
.SqlLab {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
padding: 0 10px;
pre {
padding: 0px !important;
margin: 0px;
border: none;
font-size: @font-size-s;
background-color: transparent !important;
}
.north-pane {
display: flex;
flex-direction: column;
}
#ace-editor {
height: calc(100% - 51px);
flex-grow: 1;
}
.ace_content {
height: 100%;
}
}
.SqlEditorTabs li {
a:focus {
outline: 0;
}
.ddbtn-tab {
font-size: inherit;
color: black;
&:active {
background: none;
}
svg {
vertical-align: middle;
}
}
.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 {
padding-top: 2px;
}
}
.SqlEditor {
display: flex;
flex-direction: row;
height: 100%;
.schemaPane {
transition: transform @timing-normal ease-in-out;
}
.queryPane {
flex: 1 1 auto;
padding: 10px;
overflow-y: none;
overflow-x: scroll;
}
.schemaPane-enter-done,
.schemaPane-exit {
transform: translateX(0);
z-index: 7;
}
.schemaPane-exit-active {
transform: translateX(-120%);
}
.schemaPane-enter-active {
transform: translateX(0);
max-width: 300px;
}
.schemaPane-enter,
.schemaPane-exit-done {
max-width: 0;
transform: translateX(-120%);
overflow: hidden;
}
.schemaPane-exit-done + .queryPane {
margin-left: 0;
}
.gutter {
border-top: 1px solid @gray-light;
border-bottom: 1px solid @gray-light;
width: 3%;
margin: 3px 47%;
}
.gutter.gutter-vertical {
cursor: row-resize;
}
}
.SqlEditorLeftBar {
height: 100%;
display: flex;
flex-direction: column;
.divider {
border-bottom: 1px solid @gray-bg;
margin: 15px 0;
}
}
.popover {
max-width: 400px;
}
.table-label {
margin-top: 5px;
margin-right: 10px;
float: left;
}
div.tablePopover {
opacity: 0.7 !important;
&:hover {
opacity: 1 !important;
}
}
.ace_editor.ace_editor {
//double class is better than !important
border: 1px solid @gray-light;
font-feature-settings: @font-feature-settings;
// Fira Code causes problem with Ace under Firefox
font-family: 'Menlo', 'Consolas', 'Courier New', 'Ubuntu Mono',
'source-code-pro', 'Lucida Console', monospace;
&.ace_autocomplete {
// Use !important because Ace Editor applies extra CSS at the last second
// when opening the autocomplete.
width: 520px !important;
}
}
.Select__menu-outer {
min-width: 100%;
width: inherit;
z-index: @z-index-dropdown;
}
.Select__clear-indicator {
margin-top: -2px;
}
.Select__arrow {
margin-top: 5px;
}
.ace_scroller {
background-color: @gray-bg;
}
.TableElement {
.well {
margin-top: 5px;
margin-bottom: 5px;
padding: 5px 10px;
}
.ws-el-controls {
margin-right: -0.3em;
display: flex;
}
.header-container {
display: flex;
flex: 1;
align-items: center;
width: 100%;
.table-name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
flex: 1;
}
.header-right-side {
margin-left: auto;
display: flex;
align-items: center;
margin-right: 33px;
}
}
}
.QueryTable .label {
display: inline-block;
}
.QueryTable .ant-btn {
position: static;
}
.ResultsModal .ant-modal-body {
min-height: 560px;
}
.ant-modal-body {
overflow: auto;
}
a.Link {
cursor: pointer;
}
.QueryTable .well {
padding: 3px 5px;
margin: 3px 5px;
}
.nav-tabs .ddbtn-tab {
padding: 0;
border: none;
background: none;
position: relative;
top: 2px;
&:focus {
outline: 0;
}
&:active {
box-shadow: none;
}
}
.icon-container {
display: inline-block;
width: 30px;
text-align: center;
}
.search-date-filter-container {
display: flex;
.Select {
margin-right: 3px;
}
}
.cost-estimate {
font-size: @font-size-s;
}