This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 9fe30ab style: Pass at propagating (and enhancing) Button component
throughout Superset (#10649)
9fe30ab is described below
commit 9fe30ab71e01ba427d91fb3cd76f5535148a010f
Author: Evan Rusackas <[email protected]>
AuthorDate: Fri Aug 28 17:34:28 2020 -0700
style: Pass at propagating (and enhancing) Button component throughout
Superset (#10649)
* getting rid of weird focus/active outline ring
* Buttons... buttons _everywhere_
* linting
* Nixing views/CRUD/dataset/Button component
* fixing 2 typing errors
* fixing more TS errors
* prefer src path for include
* one more real button, one less CSS class
* one more "button" to "Button"
* Published Status is now a proper clickable Label
* nixing the CRUD button again
* touching up stories, with SupersetButton story
* SIP-34 button colors
* adding polished package to mix colors
* updating button colors to match Superset theme
* abstracting away from bootstrap-specific props (might pivot libraries
soon!)
* more abstraction from bsStyle/bsSize props
* exchanging styles for a prop
* linting
* restoring feature flag to stock
* using src alias
* last <button> replacement
* this classname would never be applied
* more linting action
* fixing unsupported bsSize 'medium', and cta typing error
* more cta action
* unnecessary styles
* errant bsSize prop
* cleanup
* tweaks to make new New button work
* Linting
* fixing a couple tests
* fixing theme based test failure
* margin tweak for NEW button
* another fixed test
* another fixed test
* fixing two more tests
* fixing last broken tests.
* always be linting
* Adding tertiary/dashed buttons
* cleaning up QueryAndSave buttons
* fixing "link" button styles
* fixing/updating link button styles
* cta buttons on Modal component
* linting.
* exporting button story knobs, making ALL knobs safe for export.
* capitalizing a file... no big whoop
* Basic button tests
* renaming button - temporarily
* renaming file to fix capitalization issue
* passing theme through to a difficult popover.
* fixin' a newly busted unit test
* lint fixin'
* oops, shouldn't have changed this prop!
* adding a dive() to themedShallow, and fixing a cypress/jest test
* addressing lint stuff
* touching up stories, with SupersetButton story
* SIP-34 button colors
* updating button colors to match Superset theme
* abstracting away from bootstrap-specific props (might pivot libraries
soon!)
* linting
* restoring feature flag to stock
* cleanup
* Linting
* renaming button - temporarily
* renaming file to fix capitalization issue
* oops, shouldn't have changed this prop!
* adding a dive() to themedShallow, and fixing a cypress/jest test
* addressing lint stuff
* nixing new modal button
* Fixing another popover/button issue that should break cypress
* lint :sparkles:
* passing classNames through to new button (should fix some tests)
* cleaning unused classes, making cypress tests use data attrs
* fixin' the test
* fixing another class-based test with data-test attr
* no longer passing theme as prop to buttons in popovers... themeprovider
is better
* outline/border tweaks!
---
.../integration/explore/AdhocFilters.test.ts | 4 +-
.../integration/explore/AdhocMetrics.test.ts | 8 +-
.../cypress/integration/explore/advanced.test.ts | 4 +-
.../cypress/integration/explore/control.test.ts | 2 +-
superset-frontend/package-lock.json | 8 +-
superset-frontend/package.json | 1 +
superset-frontend/spec/helpers/theming.ts | 2 +-
.../addSlice/AddSliceContainer_spec.tsx | 14 +-
.../components/ConfirmStatusChange_spec.jsx | 6 +-
.../components/gridComponents/Tab_spec.jsx | 2 +-
.../datasource/DatasourceModal_spec.jsx | 5 +-
.../components/AdhocFilterEditPopover_spec.jsx | 7 +-
.../explore/components/AdhocFilterOption_spec.jsx | 4 +-
.../components/AdhocMetricEditPopover_spec.jsx | 7 +-
.../explore/components/AdhocMetricOption_spec.jsx | 4 +-
.../explore/components/DateFilterControl_spec.jsx | 2 +-
.../explore/components/QueryAndSaveBtns_spec.jsx | 2 +-
.../explore/components/SaveModal_spec.jsx | 6 +-
.../spec/javascripts/sqllab/QuerySearch_spec.jsx | 2 +-
.../spec/javascripts/sqllab/SouthPane_spec.jsx | 2 +-
superset-frontend/src/CRUD/CollectionTable.tsx | 4 +-
.../SqlLab/components/EstimateQueryCostButton.jsx | 6 +-
.../SqlLab/components/ExploreCtasResultsButton.jsx | 4 +-
.../src/SqlLab/components/ExploreResultsButton.jsx | 6 +-
.../src/SqlLab/components/LimitControl.tsx | 15 +-
.../src/SqlLab/components/QuerySearch.jsx | 6 +-
.../src/SqlLab/components/QueryTable.jsx | 22 +-
.../src/SqlLab/components/ResultSet.tsx | 19 +-
.../src/SqlLab/components/RunQueryActionButton.tsx | 14 +-
.../src/SqlLab/components/SaveQuery.jsx | 6 +-
.../src/SqlLab/components/ScheduleQueryButton.jsx | 2 +-
.../src/SqlLab/components/ShareSqlLabQuery.jsx | 4 +-
.../src/SqlLab/components/SqlEditor.jsx | 4 +-
.../src/SqlLab/components/SqlEditorLeftBar.jsx | 8 +-
.../src/SqlLab/components/TemplateParamsEditor.jsx | 2 +-
.../src/addSlice/AddSliceContainer.tsx | 5 +-
superset-frontend/src/common/components/Modal.tsx | 2 +-
.../{button.stories.jsx => Button.stories.jsx} | 73 +++----
.../src/components/Button/Button.test.tsx | 68 ++++++
superset-frontend/src/components/Button/index.tsx | 232 ++++++++++++++++++---
.../src/components/ErrorMessage/ErrorAlert.tsx | 8 +-
.../src/components/ExpandableList.tsx | 4 +-
.../src/components/Label/Label.stories.tsx | 2 +-
.../src/components/ListView/ListView.tsx | 3 +-
superset-frontend/src/components/Menu/Menu.tsx | 8 +
superset-frontend/src/components/Menu/NewMenu.tsx | 13 +-
superset-frontend/src/components/Menu/SubMenu.tsx | 14 +-
superset-frontend/src/components/Modal.tsx | 12 +-
superset-frontend/src/components/ModalTrigger.jsx | 8 +-
.../src/components/RefreshChartOverlay.tsx | 2 +-
.../dashboard/components/DeleteComponentModal.jsx | 4 +-
.../src/dashboard/components/Header.jsx | 22 +-
.../src/dashboard/components/PropertiesModal.jsx | 18 +-
.../src/dashboard/components/PublishedStatus.jsx | 23 +-
.../dashboard/components/RefreshIntervalModal.jsx | 7 +-
.../src/dashboard/components/SaveModal.jsx | 5 +-
.../components/filterscope/FilterScopeSelector.jsx | 6 +-
.../src/dashboard/stylesheets/buttons.less | 11 -
.../src/datasource/DatasourceEditor.jsx | 2 +-
.../src/datasource/DatasourceModal.tsx | 14 +-
.../explore/components/AdhocFilterEditPopover.jsx | 124 ++++++-----
.../src/explore/components/AdhocFilterOption.jsx | 10 +-
.../explore/components/AdhocMetricEditPopover.jsx | 188 +++++++++--------
.../src/explore/components/AdhocMetricOption.jsx | 9 +-
.../src/explore/components/DisplayQueryButton.jsx | 2 +-
.../explore/components/ExploreActionButtons.jsx | 2 +-
.../src/explore/components/PropertiesModal.tsx | 10 +-
.../src/explore/components/QueryAndSaveBtns.jsx | 28 +--
.../src/explore/components/SaveModal.jsx | 25 +--
.../components/controls/AnnotationLayer.jsx | 20 +-
.../components/controls/AnnotationLayerControl.jsx | 7 +-
.../components/controls/DateFilterControl.jsx | 9 +-
.../explore/components/controls/SpatialControl.jsx | 7 +-
.../components/controls/TextAreaControl.jsx | 5 +-
.../src/views/CRUD/data/dataset/Button.tsx | 72 -------
.../src/visualizations/FilterBox/FilterBox.jsx | 6 +-
superset-frontend/stylesheets/superset.less | 4 +
.../SqlLab/components/ExploreCtasResultsButton.jsx | 4 +-
78 files changed, 755 insertions(+), 557 deletions(-)
diff --git
a/superset-frontend/cypress-base/cypress/integration/explore/AdhocFilters.test.ts
b/superset-frontend/cypress-base/cypress/integration/explore/AdhocFilters.test.ts
index dc12961..576304a 100644
---
a/superset-frontend/cypress-base/cypress/integration/explore/AdhocFilters.test.ts
+++
b/superset-frontend/cypress-base/cypress/integration/explore/AdhocFilters.test.ts
@@ -40,7 +40,7 @@ describe('AdhocFilters', () => {
cy.get('button').contains('Save').click();
});
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
chartSelector: 'svg',
@@ -63,7 +63,7 @@ describe('AdhocFilters', () => {
cy.get('button').contains('Save').click();
});
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
chartSelector: 'svg',
diff --git
a/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
b/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
index 59722a0..5dfd741 100644
---
a/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
+++
b/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
@@ -48,7 +48,7 @@ describe('AdhocMetrics', () => {
cy.get('.metrics-select .metric-option').contains(metricName);
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
querySubstring: `${metric} AS "${metricName}"`, // SQL statement
@@ -77,7 +77,7 @@ describe('AdhocMetrics', () => {
.type('/COUNT(DISTINCT name)', { force: true });
cy.get('#metrics-edit-popover').find('button').contains('Save').click();
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
const metric = 'SUM(num)/COUNT(DISTINCT name)';
cy.verifySliceSuccess({
@@ -103,7 +103,7 @@ describe('AdhocMetrics', () => {
cy.get('button').contains('Save').click();
});
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
const metric = 'SUM(num)';
cy.verifySliceSuccess({
@@ -124,7 +124,7 @@ describe('AdhocMetrics', () => {
});
const metric = 'AVG(sum_boys)';
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
querySubstring: `${metric} AS "${metric}"`,
diff --git
a/superset-frontend/cypress-base/cypress/integration/explore/advanced.test.ts
b/superset-frontend/cypress-base/cypress/integration/explore/advanced.test.ts
index 624bac6..31291e3 100644
---
a/superset-frontend/cypress-base/cypress/integration/explore/advanced.test.ts
+++
b/superset-frontend/cypress-base/cypress/integration/explore/advanced.test.ts
@@ -43,7 +43,7 @@ describe('Advanced analytics', () => {
.find('.Select__multi-value__label')
.contains('364 days');
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.wait('@postJson');
cy.reload();
cy.verifySliceSuccess({
@@ -90,7 +90,7 @@ describe('Annotations', () => {
cy.get('button').contains('OK').click();
});
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
chartSelector: 'svg',
diff --git
a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
index f906958..7a08611 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
@@ -78,7 +78,7 @@ describe('Groupby control', () => {
cy.get('.Select__control').click();
cy.get('input[type=text]').type('state{enter}');
});
- cy.get('button.query').click();
+ cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({ waitAlias: '@postJson', chartSelector: 'svg' });
});
});
diff --git a/superset-frontend/package-lock.json
b/superset-frontend/package-lock.json
index 18da52a..ecc9c29 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -34830,16 +34830,14 @@
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/polished/-/polished-3.6.5.tgz",
"integrity":
"sha512-VwhC9MlhW7O5dg/z7k32dabcAFW1VI2+7fSe8cE/kXcfL7mVdoa5UxciYGW2sJU78ldDLT6+ROEKIZKFNTnUXQ==",
- "dev": true,
"requires": {
"@babel/runtime": "^7.9.2"
},
"dependencies": {
"@babel/runtime": {
- "version": "7.10.5",
- "resolved":
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.5.tgz",
- "integrity":
"sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==",
- "dev": true,
+ "version": "7.11.2",
+ "resolved":
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz",
+ "integrity":
"sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index cb00328..4302995 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -145,6 +145,7 @@
"mousetrap": "^1.6.1",
"mustache": "^2.2.1",
"omnibar": "^2.1.1",
+ "polished": "^3.6.5",
"prop-types": "^15.7.2",
"re-resizable": "^4.3.1",
"react": "^16.13.1",
diff --git a/superset-frontend/spec/helpers/theming.ts
b/superset-frontend/spec/helpers/theming.ts
index cf1b462..7f83165 100644
--- a/superset-frontend/spec/helpers/theming.ts
+++ b/superset-frontend/spec/helpers/theming.ts
@@ -51,5 +51,5 @@ export function styledShallow(
theme: supersetTheme,
...options?.wrappingComponentProps,
},
- });
+ }).dive();
}
diff --git
a/superset-frontend/spec/javascripts/addSlice/AddSliceContainer_spec.tsx
b/superset-frontend/spec/javascripts/addSlice/AddSliceContainer_spec.tsx
index 5db740d..4af7fec 100644
--- a/superset-frontend/spec/javascripts/addSlice/AddSliceContainer_spec.tsx
+++ b/superset-frontend/spec/javascripts/addSlice/AddSliceContainer_spec.tsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Select from 'src/components/Select';
import AddSliceContainer, {
AddSliceContainerProps,
@@ -58,9 +58,9 @@ describe('AddSliceContainer', () => {
});
it('renders a disabled button if no datasource is selected', () => {
- expect(
- wrapper.find(Button).dive().find('.btn[disabled=true]'),
- ).toHaveLength(1);
+ expect(wrapper.find(Button).dive().find({ disabled: true })).toHaveLength(
+ 1,
+ );
});
it('renders an enabled button if datasource is selected', () => {
@@ -70,9 +70,9 @@ describe('AddSliceContainer', () => {
datasourceId: datasourceValue.split('__')[0],
datasourceType: datasourceValue.split('__')[1],
});
- expect(
- wrapper.find(Button).dive().find('.btn[disabled=false]'),
- ).toHaveLength(1);
+ expect(wrapper.find(Button).dive().find({ disabled: true })).toHaveLength(
+ 0,
+ );
});
it('formats explore url', () => {
diff --git
a/superset-frontend/spec/javascripts/components/ConfirmStatusChange_spec.jsx
b/superset-frontend/spec/javascripts/components/ConfirmStatusChange_spec.jsx
index a9e027d..4b00263 100644
--- a/superset-frontend/spec/javascripts/components/ConfirmStatusChange_spec.jsx
+++ b/superset-frontend/spec/javascripts/components/ConfirmStatusChange_spec.jsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import { mount } from 'enzyme';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import Modal from 'src/components/Modal';
@@ -33,7 +33,7 @@ describe('ConfirmStatusChange', () => {
<ConfirmStatusChange {...mockedProps}>
{confirm => (
<>
- <button id="btn1" onClick={confirm} />
+ <Button id="btn1" onClick={confirm} />
</>
)}
</ConfirmStatusChange>,
@@ -44,7 +44,7 @@ describe('ConfirmStatusChange', () => {
);
it('opens a confirm modal', () => {
- wrapper.find('#btn1').props().onClick('foo');
+ wrapper.find('#btn1').first().props().onClick('foo');
wrapper.update();
diff --git
a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx
b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx
index 0d07255..059de56 100644
---
a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx
+++
b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx
@@ -18,7 +18,7 @@
*/
import { Provider } from 'react-redux';
import React from 'react';
-import { mount } from 'enzyme';
+import { styledMount as mount } from 'spec/helpers/theming';
import sinon from 'sinon';
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
diff --git
a/superset-frontend/spec/javascripts/datasource/DatasourceModal_spec.jsx
b/superset-frontend/spec/javascripts/datasource/DatasourceModal_spec.jsx
index be5111c..f8bf0c0 100644
--- a/superset-frontend/spec/javascripts/datasource/DatasourceModal_spec.jsx
+++ b/superset-frontend/spec/javascripts/datasource/DatasourceModal_spec.jsx
@@ -83,7 +83,10 @@ describe('DatasourceModal', () => {
it('saves on confirm', async () => {
act(() => {
- wrapper.find('[className="m-r-5"]').props().onClick();
+ wrapper
+ .find('button[data-test="datasource-modal-save"]')
+ .props()
+ .onClick();
});
await waitForComponentToPaint(wrapper);
act(() => {
diff --git
a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
index 022ee1d..652c162 100644
---
a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
@@ -20,7 +20,8 @@
import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
-import { Button, Popover, Tab, Tabs } from 'react-bootstrap';
+import { Popover, Tab, Tabs } from 'react-bootstrap';
+import Button from 'src/components/Button';
import AdhocFilter, {
EXPRESSION_TYPES,
@@ -117,9 +118,9 @@ describe('AdhocFilterEditPopover', () => {
it('highlights save if changes are present', () => {
const { wrapper } = setup();
- expect(wrapper.find(Button).find({ bsStyle: 'primary' })).not.toExist();
+ expect(wrapper.find(Button).find({ buttonStyle: 'primary'
})).not.toExist();
wrapper.instance().onAdhocFilterChange(sqlAdhocFilter);
- expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toExist();
+ expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).toExist();
});
it('will initiate a drag when clicked', () => {
diff --git
a/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
index f2e9ffe..118ef32 100644
---
a/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
@@ -19,7 +19,7 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
-import { shallow } from 'enzyme';
+import { styledShallow as shallow } from 'spec/helpers/theming';
import { OverlayTrigger } from 'react-bootstrap';
import Label from 'src/components/Label';
@@ -46,7 +46,7 @@ function setup(overrides) {
datasource: {},
...overrides,
};
- const wrapper = shallow(<AdhocFilterOption {...props} />);
+ const wrapper = shallow(<AdhocFilterOption {...props} />).dive();
return { wrapper };
}
diff --git
a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
index e66f6ae..2f15017 100644
---
a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
@@ -20,7 +20,8 @@
import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
-import { Button, FormGroup, Popover } from 'react-bootstrap';
+import { FormGroup, Popover } from 'react-bootstrap';
+import Button from 'src/components/Button';
import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
import AdhocMetricEditPopover from
'src/explore/components/AdhocMetricEditPopover';
@@ -117,9 +118,9 @@ describe('AdhocMetricEditPopover', () => {
it('highlights save if changes are present', () => {
const { wrapper } = setup();
- expect(wrapper.find(Button).find({ bsStyle: 'primary' })).not.toExist();
+ expect(wrapper.find(Button).find({ buttonStyle: 'primary'
})).not.toExist();
wrapper.instance().onColumnChange({ column: columns[1] });
- expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toExist();
+ expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).toExist();
});
it('will initiate a drag when clicked', () => {
diff --git
a/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
index 0612f6c..5b23da2 100644
---
a/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
@@ -19,7 +19,7 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
-import { shallow } from 'enzyme';
+import { styledShallow as shallow } from 'spec/helpers/theming';
import { OverlayTrigger } from 'react-bootstrap';
import Label from 'src/components/Label';
@@ -46,7 +46,7 @@ function setup(overrides) {
columns,
...overrides,
};
- const wrapper = shallow(<AdhocMetricOption {...props} />);
+ const wrapper = shallow(<AdhocMetricOption {...props} />).dive();
return { wrapper, onMetricEdit };
}
diff --git
a/superset-frontend/spec/javascripts/explore/components/DateFilterControl_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/DateFilterControl_spec.jsx
index 5a93af1..693c869 100644
---
a/superset-frontend/spec/javascripts/explore/components/DateFilterControl_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/DateFilterControl_spec.jsx
@@ -20,7 +20,7 @@
import React from 'react';
import sinon from 'sinon';
import { styledMount as mount } from 'spec/helpers/theming';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Label from 'src/components/Label';
import DateFilterControl from
'src/explore/components/controls/DateFilterControl';
diff --git
a/superset-frontend/spec/javascripts/explore/components/QueryAndSaveBtns_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/QueryAndSaveBtns_spec.jsx
index 2126265..7c32361 100644
---
a/superset-frontend/spec/javascripts/explore/components/QueryAndSaveBtns_spec.jsx
+++
b/superset-frontend/spec/javascripts/explore/components/QueryAndSaveBtns_spec.jsx
@@ -54,7 +54,7 @@ describe('QueryAndSaveButtons', () => {
});
it('calls onQuery when query button is clicked', () => {
- const queryButton = wrapper.find('.query');
+ const queryButton = wrapper.find('[data-test="run-query-button"]');
queryButton.simulate('click');
expect(defaultProps.onQuery.called).toBe(true);
});
diff --git
a/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx
b/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx
index 4348b9b..b419a7b 100644
--- a/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx
@@ -21,8 +21,10 @@ import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { bindActionCreators } from 'redux';
-import { shallow, mount } from 'enzyme';
-import { FormControl, Modal, Button, Radio } from 'react-bootstrap';
+import { shallow } from 'enzyme';
+import { styledMount as mount } from 'spec/helpers/theming';
+import { FormControl, Modal, Radio } from 'react-bootstrap';
+import Button from 'src/components/Button';
import sinon from 'sinon';
import fetchMock from 'fetch-mock';
diff --git a/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx
b/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx
index 5d853dc..68ae9e8 100644
--- a/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx
+++ b/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx
@@ -17,7 +17,7 @@
* under the License.
*/
import React from 'react';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { shallow } from 'enzyme';
import sinon from 'sinon';
diff --git a/superset-frontend/spec/javascripts/sqllab/SouthPane_spec.jsx
b/superset-frontend/spec/javascripts/sqllab/SouthPane_spec.jsx
index 64f0164..75a8519 100644
--- a/superset-frontend/spec/javascripts/sqllab/SouthPane_spec.jsx
+++ b/superset-frontend/spec/javascripts/sqllab/SouthPane_spec.jsx
@@ -78,7 +78,7 @@ describe('SouthPane', () => {
const getWrapper = () =>
shallow(<SouthPaneContainer {...mockedProps} />, {
context: { store },
- }).dive();
+ });
let wrapper;
diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx
b/superset-frontend/src/CRUD/CollectionTable.tsx
index dfa89b0..11d3105 100644
--- a/superset-frontend/src/CRUD/CollectionTable.tsx
+++ b/superset-frontend/src/CRUD/CollectionTable.tsx
@@ -19,7 +19,7 @@
import React, { ReactNode } from 'react';
import shortid from 'shortid';
import { t } from '@superset-ui/translation';
-import Button from '../components/Button';
+import Button from 'src/components/Button';
import Fieldset from './Fieldset';
import { recurseReactClone } from './utils';
import './crud.less';
@@ -167,7 +167,7 @@ export default class CRUDCollection extends
React.PureComponent<
{allowDeletes && !allowAddItem && <th className="tiny-cell" />}
{allowAddItem && (
<th>
- <Button bsStyle="primary" onClick={this.onAddItem}>
+ <Button buttonStyle="primary" onClick={this.onAddItem}>
<i className="fa fa-plus" /> {t('Add Item')}
</Button>
</th>
diff --git
a/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
b/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
index 9de7808..69d0095 100644
--- a/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
+++ b/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
@@ -22,7 +22,7 @@ import { Table } from 'reactable-arc';
import { Alert } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import Button from '../../components/Button';
+import Button from 'src/components/Button';
import Loading from '../../components/Loading';
import ModalTrigger from '../../components/ModalTrigger';
@@ -85,8 +85,8 @@ class EstimateQueryCostButton extends React.PureComponent {
modalBody={this.renderModalBody()}
triggerNode={
<Button
- bsStyle="warning"
- bsSize="small"
+ buttonStyle="warning"
+ buttonSize="small"
onClick={this.onClick}
key="query-estimate-btn"
tooltip={tooltip}
diff --git
a/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx
b/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx
index 390bfbc..ff48a61 100644
--- a/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx
+++ b/superset-frontend/src/SqlLab/components/ExploreCtasResultsButton.jsx
@@ -24,9 +24,9 @@ import Dialog from 'react-bootstrap-dialog';
import { t } from '@superset-ui/translation';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
+import Button from 'src/components/Button';
import { exploreChart } from '../../explore/exploreUtils';
import * as actions from '../actions/sqlLab';
-import Button from '../../components/Button';
const propTypes = {
actions: PropTypes.object.isRequired,
@@ -89,7 +89,7 @@ class ExploreCtasResultsButton extends React.PureComponent {
return (
<>
<Button
- bsSize="small"
+ buttonSize="small"
onClick={this.onClick}
tooltip={t('Explore the result set in the data exploration view')}
>
diff --git a/superset-frontend/src/SqlLab/components/ExploreResultsButton.jsx
b/superset-frontend/src/SqlLab/components/ExploreResultsButton.jsx
index 8ecec6f..9a8cef6 100644
--- a/superset-frontend/src/SqlLab/components/ExploreResultsButton.jsx
+++ b/superset-frontend/src/SqlLab/components/ExploreResultsButton.jsx
@@ -25,11 +25,11 @@ import { Alert } from 'react-bootstrap';
import Dialog from 'react-bootstrap-dialog';
import { t } from '@superset-ui/translation';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
-
import shortid from 'shortid';
+
+import Button from 'src/components/Button';
import { exploreChart } from '../../explore/exploreUtils';
import * as actions from '../actions/sqlLab';
-import Button from '../../components/Button';
const propTypes = {
actions: PropTypes.object.isRequired,
@@ -213,7 +213,7 @@ class ExploreResultsButton extends React.PureComponent {
return (
<>
<Button
- bsSize="small"
+ buttonSize="small"
onClick={this.onClick}
disabled={!allowsSubquery}
tooltip={t('Explore the result set in the data exploration view')}
diff --git a/superset-frontend/src/SqlLab/components/LimitControl.tsx
b/superset-frontend/src/SqlLab/components/LimitControl.tsx
index 9b55dce..ee2750b 100644
--- a/superset-frontend/src/SqlLab/components/LimitControl.tsx
+++ b/superset-frontend/src/SqlLab/components/LimitControl.tsx
@@ -17,13 +17,8 @@
* under the License.
*/
import React from 'react';
-import {
- Button,
- FormGroup,
- FormControl,
- Overlay,
- Popover,
-} from 'react-bootstrap';
+import { FormGroup, FormControl, Overlay, Popover } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import styled from '@superset-ui/style';
@@ -119,8 +114,8 @@ export default class LimitControl extends
React.PureComponent<
</FormGroup>
<div className="clearfix">
<Button
- bsSize="small"
- bsStyle="primary"
+ buttonSize="small"
+ buttonStyle="primary"
className="float-right ok m-l-5"
disabled={!isValid}
onClick={this.submitAndClose}
@@ -128,7 +123,7 @@ export default class LimitControl extends
React.PureComponent<
{t('Ok')}
</Button>
<Button
- bsSize="small"
+ buttonSize="small"
className="float-right reset"
onClick={this.setValueAndClose.bind(
this,
diff --git a/superset-frontend/src/SqlLab/components/QuerySearch.jsx
b/superset-frontend/src/SqlLab/components/QuerySearch.jsx
index d7f0e90..f75ed10 100644
--- a/superset-frontend/src/SqlLab/components/QuerySearch.jsx
+++ b/superset-frontend/src/SqlLab/components/QuerySearch.jsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Select from 'src/components/Select';
import { t } from '@superset-ui/translation';
import { SupersetClient } from '@superset-ui/connection';
@@ -273,8 +273,8 @@ class QuerySearch extends React.PureComponent {
/>
<Button
- bsSize="small"
- bsStyle="success"
+ buttonSize="small"
+ buttonStyle="success"
onClick={this.refreshQueries}
>
{t('Search')}
diff --git a/superset-frontend/src/SqlLab/components/QueryTable.jsx
b/superset-frontend/src/SqlLab/components/QueryTable.jsx
index 6c3ec80..969bed8 100644
--- a/superset-frontend/src/SqlLab/components/QueryTable.jsx
+++ b/superset-frontend/src/SqlLab/components/QueryTable.jsx
@@ -24,6 +24,7 @@ import { ProgressBar, Well } from 'react-bootstrap';
import Label from 'src/components/Label';
import { t } from '@superset-ui/translation';
+import Button from 'src/components/Button';
import Link from '../../components/Link';
import ResultSet from './ResultSet';
import ModalTrigger from '../../components/ModalTrigger';
@@ -99,31 +100,34 @@ class QueryTable extends React.PureComponent {
</div>
);
q.user = (
- <button
- className="btn btn-link btn-xs"
+ <Button
+ buttonSize="small"
+ buttonStyle="link"
onClick={this.props.onUserClicked.bind(this, q.userId)}
>
{q.user}
- </button>
+ </Button>
);
q.db = (
- <button
- className="btn btn-link btn-xs"
+ <Button
+ buttonSize="small"
+ buttonStyle="link"
onClick={this.props.onDbClicked.bind(this, q.dbId)}
>
{q.db}
- </button>
+ </Button>
);
q.started = moment(q.startDttm).format('HH:mm:ss');
q.querylink = (
<div style={{ width: '100px' }}>
- <button
- className="btn btn-link btn-xs"
+ <Button
+ buttonSize="small"
+ buttonStyle="link"
onClick={this.openQuery.bind(this, q.queryId)}
>
<i className="fa fa-external-link m-r-3" />
{t('Edit')}
- </button>
+ </Button>
</div>
);
q.sql = (
diff --git a/superset-frontend/src/SqlLab/components/ResultSet.tsx
b/superset-frontend/src/SqlLab/components/ResultSet.tsx
index db154fb..db40267 100644
--- a/superset-frontend/src/SqlLab/components/ResultSet.tsx
+++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx
@@ -17,7 +17,8 @@
* under the License.
*/
import React, { CSSProperties } from 'react';
-import { Alert, Button, ButtonGroup, ProgressBar } from 'react-bootstrap';
+import { Alert, ButtonGroup, ProgressBar } from 'react-bootstrap';
+import Button from 'src/components/Button';
import shortid from 'shortid';
import { t } from '@superset-ui/translation';
@@ -166,7 +167,7 @@ export default class ResultSet extends React.PureComponent<
)}
{this.props.csv && (
<Button
- bsSize="small"
+ buttonSize="small"
href={`/superset/csv/${this.props.query.id}`}
>
<i className="fa fa-file-text-o" /> {t('.CSV')}
@@ -177,7 +178,7 @@ export default class ResultSet extends React.PureComponent<
text={prepareCopyToClipboardTabularData(data)}
wrapped={false}
copyNode={
- <Button bsSize="small">
+ <Button buttonSize="small">
<i className="fa fa-clipboard" /> {t('Clipboard')}
</Button>
}
@@ -243,7 +244,7 @@ export default class ResultSet extends React.PureComponent<
] {t('was created')}
<ButtonGroup>
<Button
- bsSize="small"
+ buttonSize="small"
className="m-r-5"
onClick={() => this.popSelectStar(tempSchema, tempTable)}
>
@@ -296,9 +297,9 @@ export default class ResultSet extends React.PureComponent<
if (query.isDataPreview) {
return (
<Button
- bsSize="sm"
+ buttonSize="sm"
className="fetch"
- bsStyle="primary"
+ buttonStyle="primary"
onClick={() =>
this.reFetchQueryResults({
...query,
@@ -312,9 +313,9 @@ export default class ResultSet extends React.PureComponent<
} else if (query.resultsKey) {
return (
<Button
- bsSize="sm"
+ buttonSize="sm"
className="fetch"
- bsStyle="primary"
+ buttonStyle="primary"
onClick={() => this.fetchResults(query)}
>
{t('Refetch Results')}
@@ -336,7 +337,7 @@ export default class ResultSet extends React.PureComponent<
if (query.trackingUrl) {
trackingUrl = (
<Button
- bsSize="small"
+ buttonSize="small"
onClick={() => query.trackingUrl && window.open(query.trackingUrl)}
>
{t('Track Job')}
diff --git a/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
b/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
index 7b4fd1e..0dffab4 100644
--- a/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
+++ b/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
@@ -19,7 +19,7 @@
import React from 'react';
import { t } from '@superset-ui/translation';
-import Button, { ButtonProps } from '../../components/Button';
+import Button, { ButtonProps } from 'src/components/Button';
const NO_OP = () => undefined;
@@ -32,9 +32,6 @@ interface Props {
stopQuery: () => void;
sql: string;
}
-const commonBtnStyle = {
- width: '140px',
-};
const RunQueryActionButton = ({
allowAsync = false,
@@ -51,15 +48,14 @@ const RunQueryActionButton = ({
!!queryState && ['running', 'pending'].indexOf(queryState) > -1;
const commonBtnProps: ButtonProps = {
- bsSize: 'small',
- bsStyle: btnStyle,
+ buttonSize: 'small',
+ buttonStyle: btnStyle,
disabled: !dbId,
- style: commonBtnStyle,
};
if (shouldShowStopBtn) {
return (
- <Button {...commonBtnProps} onClick={stopQuery}>
+ <Button {...commonBtnProps} cta onClick={stopQuery}>
<i className="fa fa-stop" /> {t('Stop')}
</Button>
);
@@ -67,6 +63,7 @@ const RunQueryActionButton = ({
return (
<Button
{...commonBtnProps}
+ cta
onClick={() => runQuery(true)}
key="run-async-btn"
tooltip={t('Run query asynchronously (Ctrl + ↵)')}
@@ -79,6 +76,7 @@ const RunQueryActionButton = ({
return (
<Button
{...commonBtnProps}
+ cta
onClick={() => runQuery(false)}
key="run-btn"
tooltip={t('Run query synchronously (Ctrl + ↵)')}
diff --git a/superset-frontend/src/SqlLab/components/SaveQuery.jsx
b/superset-frontend/src/SqlLab/components/SaveQuery.jsx
index b9eb2de..5e7a878 100644
--- a/superset-frontend/src/SqlLab/components/SaveQuery.jsx
+++ b/superset-frontend/src/SqlLab/components/SaveQuery.jsx
@@ -135,7 +135,7 @@ class SaveQuery extends React.PureComponent {
<Col md={12}>
{isSaved && (
<Button
- bsStyle="primary"
+ buttonStyle="primary"
onClick={this.onUpdate}
className="m-r-3"
>
@@ -143,7 +143,7 @@ class SaveQuery extends React.PureComponent {
</Button>
)}
<Button
- bsStyle={isSaved ? undefined : 'primary'}
+ buttonStyle={isSaved ? undefined : 'primary'}
onClick={this.onSave}
className="m-r-3"
>
@@ -169,7 +169,7 @@ class SaveQuery extends React.PureComponent {
backdrop="static"
triggerNode={
<Button
- bsSize="small"
+ buttonSize="small"
className="toggleSave"
onClick={this.toggleSave}
>
diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
index 08fd388..ed710c0 100644
--- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
+++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
@@ -192,7 +192,7 @@ class ScheduleQueryButton extends React.PureComponent {
modalBody={this.renderModalBody()}
triggerNode={
<Button
- bsSize="small"
+ buttonSize="small"
className="toggleSchedule"
onClick={this.toggleSchedule}
disabled={this.props.disabled}
diff --git a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery.jsx
b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery.jsx
index cb7d133..75291db 100644
--- a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery.jsx
+++ b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery.jsx
@@ -22,7 +22,7 @@ import { Popover, OverlayTrigger } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
-import Button from '../../components/Button';
+import Button from 'src/components/Button';
import CopyToClipboard from '../../components/CopyToClipboard';
import { storeQuery } from '../../utils/common';
import getClientErrorObject from '../../utils/getClientErrorObject';
@@ -110,7 +110,7 @@ class ShareSqlLabQuery extends React.Component {
shouldUpdatePosition
overlay={this.renderPopover()}
>
- <Button bsSize="small" className="toggleSave">
+ <Button buttonSize="small" className="toggleSave">
<i className="fa fa-share" /> {t('Share')}
</Button>
</OverlayTrigger>
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor.jsx
b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
index 976a3be..4f3e72c 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
@@ -398,7 +398,7 @@ class SqlEditor extends React.PureComponent {
<InputGroup.Button>
{this.props.database.allow_ctas && (
<Button
- bsSize="small"
+ buttonSize="small"
disabled={this.state.ctas.length === 0}
onClick={this.createTableAs.bind(this)}
tooltip={ctasToolTip}
@@ -408,7 +408,7 @@ class SqlEditor extends React.PureComponent {
)}
{this.props.database.allow_cvas && (
<Button
- bsSize="small"
+ buttonSize="small"
disabled={this.state.ctas.length === 0}
onClick={this.createViewAs.bind(this)}
tooltip={cvasToolTip}
diff --git a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
index 0f2ac94..6bb7546 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import TableElement from './TableElement';
import TableSelector from '../../components/TableSelector';
@@ -140,7 +140,11 @@ export default class SqlEditorLeftBar extends
React.PureComponent {
</div>
</div>
{shouldShowReset && (
- <Button bsSize="small" bsStyle="danger" onClick={this.resetState}>
+ <Button
+ buttonSize="small"
+ buttonStyle="danger"
+ onClick={this.resetState}
+ >
<i className="fa fa-bomb" /> {t('Reset State')}
</Button>
)}
diff --git a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
index 7127cc3..15f6572 100644
--- a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
+++ b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
@@ -29,8 +29,8 @@ import 'brace/theme/textmate';
import { t } from '@superset-ui/translation';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
+import Button from 'src/components/Button';
import ModalTrigger from '../../components/ModalTrigger';
-import Button from '../../components/Button';
const propTypes = {
onChange: PropTypes.func,
diff --git a/superset-frontend/src/addSlice/AddSliceContainer.tsx
b/superset-frontend/src/addSlice/AddSliceContainer.tsx
index fbcd3b3..436397d 100644
--- a/superset-frontend/src/addSlice/AddSliceContainer.tsx
+++ b/superset-frontend/src/addSlice/AddSliceContainer.tsx
@@ -17,7 +17,8 @@
* under the License.
*/
import React from 'react';
-import { Button, Panel } from 'react-bootstrap';
+import { Panel } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Select from 'src/components/Select';
import { t } from '@superset-ui/translation';
@@ -142,7 +143,7 @@ export default class AddSliceContainer extends
React.PureComponent<
<br />
<hr />
<Button
- bsStyle="primary"
+ buttonStyle="primary"
disabled={this.isBtnDisabled()}
onClick={this.gotoSlice}
>
diff --git a/superset-frontend/src/common/components/Modal.tsx
b/superset-frontend/src/common/components/Modal.tsx
index ab29c9f..9757315 100644
--- a/superset-frontend/src/common/components/Modal.tsx
+++ b/superset-frontend/src/common/components/Modal.tsx
@@ -20,7 +20,7 @@ import React from 'react';
import styled from '@superset-ui/style';
import { Modal as BaseModal } from 'src/common/components';
import { t } from '@superset-ui/translation';
-import Button from 'src/views/CRUD/data/dataset/Button';
+import Button from 'src/components/Button';
interface ModalProps {
className?: string;
diff --git a/superset-frontend/src/components/Button/button.stories.jsx
b/superset-frontend/src/components/Button/Button.stories.jsx
similarity index 74%
rename from superset-frontend/src/components/Button/button.stories.jsx
rename to superset-frontend/src/components/Button/Button.stories.jsx
index d93474c..3c578e8 100644
--- a/superset-frontend/src/components/Button/button.stories.jsx
+++ b/superset-frontend/src/components/Button/Button.stories.jsx
@@ -25,13 +25,16 @@ export default {
title: 'Button',
component: Button,
decorators: [withKnobs],
+ excludeStories: /.*Knob$/,
};
-const bsStyleKnob = {
+export const buttonStyleKnob = {
label: 'Types',
options: {
Primary: 'primary',
Secondary: 'secondary',
+ Tertiary: 'tertiary',
+ Dashed: 'dashed',
Danger: 'danger',
Warning: 'warning',
Success: 'success',
@@ -42,17 +45,18 @@ const bsStyleKnob = {
defaultValue: null,
// groupId: 'ButtonType',
};
-const bsSizeKnob = {
+
+export const buttonSizeKnob = {
label: 'Sizes',
options: {
XS: 'xsmall',
S: 'small',
- M: 'medium',
+ Default: null,
L: 'large',
- None: null,
},
defaultValue: null,
};
+
// TODO remove the use of these in the codebase where they're not necessary
// const classKnob = {
// label: 'Known Classes',
@@ -62,7 +66,6 @@ const bsSizeKnob = {
// Reset: 'reset',
// Fetch: 'fetch',
// Query: 'query',
-// saveBtn: 'save-btn',
// MR3: 'm-r-3',
// cancelQuery: 'cancelQuery',
// toggleSave: 'toggleSave',
@@ -101,43 +104,43 @@ const hrefKnob = {
export const ButtonGallery = () => (
<>
- {Object.values(bsSizeKnob.options)
- .filter(a => a)
- .map(size => (
- <div>
- <h4>{size}</h4>
- {Object.values(bsStyleKnob.options)
- .filter(o => o)
- .map(style => (
- <Button
- disabled={boolean('Disabled', false)}
- bsStyle={style}
- bsSize={size}
- onClick={action('clicked')}
- style={{ marginRight: 5 }}
- >
- {style}
- </Button>
- ))}
- </div>
- ))}
+ {Object.entries(buttonSizeKnob.options).map(([name, size]) => (
+ <div key={size}>
+ <h4>{name}</h4>
+ {Object.values(buttonStyleKnob.options)
+ .filter(o => o)
+ .map(style => (
+ <Button
+ disabled={boolean('Disabled', false)}
+ cta={boolean('CTA', false)}
+ buttonStyle={style}
+ buttonSize={size}
+ onClick={action('clicked')}
+ key={`${style}_${size}`}
+ >
+ {style}
+ </Button>
+ ))}
+ </div>
+ ))}
</>
);
export const InteractiveButton = () => (
<Button
disabled={boolean('Disabled', false)}
- bsStyle={select(
- bsStyleKnob.label,
- bsStyleKnob.options,
- bsStyleKnob.defaultValue,
- bsStyleKnob.groupId,
+ cta={boolean('CTA', false)}
+ buttonStyle={select(
+ buttonStyleKnob.label,
+ buttonStyleKnob.options,
+ buttonStyleKnob.defaultValue,
+ buttonStyleKnob.groupId,
)}
- bsSize={select(
- bsSizeKnob.label,
- bsSizeKnob.options,
- bsSizeKnob.defaultValue,
- bsSizeKnob.groupId,
+ size={select(
+ buttonSizeKnob.label,
+ buttonSizeKnob.options,
+ buttonSizeKnob.defaultValue,
+ buttonSizeKnob.groupId,
)}
onClick={action('clicked')}
type={select(
diff --git a/superset-frontend/src/components/Button/Button.test.tsx
b/superset-frontend/src/components/Button/Button.test.tsx
new file mode 100644
index 0000000..611a7db
--- /dev/null
+++ b/superset-frontend/src/components/Button/Button.test.tsx
@@ -0,0 +1,68 @@
+/**
+ * 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 { ReactWrapper } from 'enzyme';
+import { styledMount as mount } from 'spec/helpers/theming';
+import Button from '.';
+import {
+ ButtonGallery,
+ buttonSizeKnob,
+ buttonStyleKnob,
+} from './Button.stories';
+
+describe('Button', () => {
+ let wrapper: ReactWrapper;
+
+ // test the basic component
+ it('renders the base component', () => {
+ expect(React.isValidElement(<Button />)).toBe(true);
+ });
+
+ it('works with an onClick handler', () => {
+ const mockAction = jest.fn();
+ wrapper = mount(<Button onClick={mockAction} />);
+ wrapper.find('Button').first().simulate('click');
+ expect(mockAction).toHaveBeenCalled();
+ });
+
+ it('does not handle onClicks when disabled', () => {
+ const mockAction = jest.fn();
+ wrapper = mount(<Button onClick={mockAction} disabled />);
+ wrapper.find('Button').first().simulate('click');
+ expect(mockAction).toHaveBeenCalledTimes(0);
+ });
+
+ // test stories from the storybook!
+ it('All the sorybook gallery variants mount', () => {
+ wrapper = mount(<ButtonGallery />);
+
+ const permutationCount =
+ Object.values(buttonStyleKnob.options).filter(o => o).length *
+ Object.values(buttonSizeKnob.options).length;
+
+ expect(wrapper.find(Button).length).toEqual(permutationCount);
+ });
+
+ // test things NOT in the storybook!
+ it('renders custom button styles without melting', () => {
+ wrapper = mount(<Button buttonStyle="foobar" />);
+ expect(wrapper.find('Button.btn-foobar')).toHaveLength(1);
+ });
+});
diff --git a/superset-frontend/src/components/Button/index.tsx
b/superset-frontend/src/components/Button/index.tsx
index a885431..d40d3f9 100644
--- a/superset-frontend/src/components/Button/index.tsx
+++ b/superset-frontend/src/components/Button/index.tsx
@@ -18,6 +18,8 @@
*/
import React from 'react';
import { kebabCase } from 'lodash';
+import { mix } from 'polished';
+import cx from 'classnames';
import {
Button as BootstrapButton,
Tooltip,
@@ -40,52 +42,201 @@ export interface ButtonProps {
placement?: string;
onClick?: OnClickHandler;
disabled?: boolean;
- bsStyle?: string;
+ buttonStyle?: string;
btnStyles?: string;
- bsSize?: BootstrapButton.ButtonProps['bsSize'];
+ buttonSize?: BootstrapButton.ButtonProps['bsSize'];
style?: BootstrapButton.ButtonProps['style'];
children?: React.ReactNode;
dropdownItems?: DropdownItemProps[];
+ href?: string; // React-Bootstrap creates a link when this is passed in.
+ target?: string; // React-Bootstrap creates a link when this is passed in.
+ type?: string; // React-Bootstrap supports this when rendering an HTML
button element
+ cta?: boolean;
}
const BUTTON_WRAPPER_STYLE = { display: 'inline-block', cursor: 'not-allowed'
};
const SupersetButton = styled(BootstrapButton)`
- &.supersetButton {
- border-radius: ${({ theme }) => theme.borderRadius}px;
- border: none;
- color: ${({ theme }) => theme.colors.secondary.light5};
- font-size: ${({ theme }) => theme.typography.sizes.s}px;
- font-weight: ${({ theme }) => theme.typography.weights.bold};
- min-width: ${({ theme }) => theme.gridUnit * 36}px;
- min-height: ${({ theme }) => theme.gridUnit * 8}px;
- text-transform: uppercase;
- margin-left: ${({ theme }) => theme.gridUnit * 4}px;
- &:first-of-type {
- margin-left: 0;
- }
+ &:focus,
+ &:active,
+ &:focus:active {
+ outline: none;
+ box-shadow: none;
+ }
+ transition: all ${({ theme }) => theme.transitionTiming}s;
+ border-radius: ${({ theme }) => theme.borderRadius}px;
+ border: none;
+ font-size: ${({ theme }) => theme.typography.sizes.s}px;
+ font-weight: ${({ theme }) => theme.typography.weights.bold};
+ margin-left: ${({ theme }) => theme.gridUnit * 4}px;
+ &:first-of-type {
+ margin-left: 0;
+ }
- i {
- padding: 0 ${({ theme }) => theme.gridUnit * 2}px 0 0;
- }
+ i {
+ padding: 0 ${({ theme }) => theme.gridUnit * 2}px 0 0;
+ }
- &.primary {
- background-color: ${({ theme }) => theme.colors.primary.base};
+ /* SIP 34 colors! */
+ &.btn {
+ border: 1px solid transparent; /* this just makes sure the height is the
same as tertiary/dashed buttons */
+ &:hover,
+ &:active {
+ border: 1px solid transparent;
}
- &.secondary {
- color: ${({ theme }) => theme.colors.primary.base};
+ &-default,
+ &-secondary {
background-color: ${({ theme }) => theme.colors.primary.light4};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5,
theme.colors.primary.light4)};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.25, theme.colors.primary.base, theme.colors.primary.light4)};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ }
+ }
+ &-tertiary,
+ &-dashed {
+ border-width: 1px;
+ border-style: solid;
+ background-color: ${({ theme }) => theme.colors.grayscale.light5};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ border-color: ${({ theme }) => theme.colors.primary.dark1};
+ &:hover {
+ background-color: ${({ theme }) => theme.colors.grayscale.light5};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ border-color: ${({ theme }) => theme.colors.primary.light1};
+ }
+ &:active {
+ background-color: ${({ theme }) => theme.colors.grayscale.light5};
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ border-color: ${({ theme }) => theme.colors.primary.dark1};
+ }
+ &[disabled],
+ &[disabled]:hover {
+ background-color: ${({ theme }) => theme.colors.grayscale.light5};
+ color: ${({ theme }) => theme.colors.grayscale.base};
+ border-color: ${({ theme }) => theme.colors.grayscale.light2};
+ }
+ }
+ &-dashed {
+ border-style: dashed;
+ &:hover,
+ &:active {
+ border-style: dashed;
+ }
}
- &.danger {
+ &-link {
+ background: none;
+ text-decoration: none;
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ &:hover {
+ background: none;
+ color: ${({ theme }) => theme.colors.primary.base};
+ }
+ &:active {
+ background: none;
+ color: ${({ theme }) => theme.colors.primary.dark1};
+ }
+ &[disabled],
+ &[disabled]:hover {
+ background: none;
+ color: ${({ theme }) => theme.colors.grayscale.base};
+ }
+ }
+ &-primary {
+ background-color: ${({ theme }) => theme.colors.primary.dark1};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5, theme.colors.primary.dark1)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.2, theme.colors.grayscale.dark2, theme.colors.primary.dark1)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ }
+ &-danger {
background-color: ${({ theme }) => theme.colors.error.base};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5, theme.colors.error.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.2, theme.colors.grayscale.dark2, theme.colors.error.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ }
+ &-success {
+ background-color: ${({ theme }) => theme.colors.success.base};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5, theme.colors.success.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.2, theme.colors.grayscale.dark2, theme.colors.success.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
}
+ &-warning {
+ background-color: ${({ theme }) => theme.colors.warning.base};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5, theme.colors.warning.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.2, theme.colors.grayscale.dark2, theme.colors.warning.base)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ }
+ &-info {
+ background-color: ${({ theme }) => theme.colors.info.dark1};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ &:hover {
+ background-color: ${({ theme }) =>
+ mix(0.1, theme.colors.grayscale.light5, theme.colors.info.dark1)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ &:active {
+ background-color: ${({ theme }) =>
+ mix(0.2, theme.colors.grayscale.dark2, theme.colors.info.dark1)};
+ color: ${({ theme }) => theme.colors.grayscale.light5};
+ }
+ }
+ &[disabled],
+ &[disabled]:hover {
+ background-color: ${({ theme }) => theme.colors.grayscale.light2};
+ color: ${({ theme }) => theme.colors.grayscale.light1};
+ }
+ }
+
+ /* big Call to Action buttons */
+ &.cta {
+ min-width: ${({ theme }) => theme.gridUnit * 36}px;
+ min-height: ${({ theme }) => theme.gridUnit * 8}px;
+ text-transform: uppercase;
}
`;
export default function Button(props: ButtonProps) {
const buttonProps = {
...props,
- bsSize: props.bsSize || 'sm',
+ bsSize: props.buttonSize,
placement: props.placement || 'top',
};
const tooltip = props.tooltip;
@@ -100,17 +251,40 @@ export default function Button(props: ButtonProps) {
buttonProps.style = { pointerEvents: 'none' };
}
+ const officialBootstrapStyles = [
+ 'success',
+ 'warning',
+ 'danger',
+ 'info',
+ 'default',
+ 'primary',
+ ];
+
+ const transformedProps = {
+ ...buttonProps,
+ bsStyle: officialBootstrapStyles.includes(props.buttonStyle || '')
+ ? props.buttonStyle
+ : 'default',
+ className: cx(props.className, {
+ cta: !!buttonProps.cta,
+ [`btn-${props.buttonStyle}`]: !officialBootstrapStyles.includes(
+ props.buttonStyle || '',
+ ),
+ }),
+ };
+ delete transformedProps.dropdownItems;
+ delete transformedProps.buttonSize;
+ delete transformedProps.buttonStyle;
+ delete transformedProps.cta;
+
let button = (
- <SupersetButton {...buttonProps}>{props.children}</SupersetButton>
+ <SupersetButton {...transformedProps}>{props.children}</SupersetButton>
);
- const whittledProps = { ...buttonProps };
- delete whittledProps.dropdownItems;
-
if (dropdownItems) {
button = (
<div style={BUTTON_WRAPPER_STYLE}>
- <SupersetButton {...whittledProps} data-toggle="dropdown">
+ <SupersetButton {...transformedProps} data-toggle="dropdown">
{props.children}
</SupersetButton>
<ul className="dropdown-menu">
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
index b176457..2b569ad 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
@@ -21,7 +21,7 @@ import { Modal } from 'react-bootstrap';
import { styled, supersetTheme } from '@superset-ui/style';
import { t } from '@superset-ui/translation';
import { noOp } from 'src/utils/common';
-import Button from 'src/views/CRUD/data/dataset/Button';
+import Button from 'src/components/Button';
import Icon from '../Icon';
import { ErrorLevel, ErrorSource } from './types';
@@ -190,7 +190,11 @@ export default function ErrorAlert({
copyNode={<Button onClick={noOp}>{t('Copy Message')}</Button>}
/>
)}
- <Button bsStyle="primary" onClick={() => setIsModalOpen(false)}>
+ <Button
+ cta
+ buttonStyle="primary"
+ onClick={() => setIsModalOpen(false)}
+ >
{t('Close')}
</Button>
</Modal.Footer>
diff --git a/superset-frontend/src/components/ExpandableList.tsx
b/superset-frontend/src/components/ExpandableList.tsx
index f827c98..20d980e 100644
--- a/superset-frontend/src/components/ExpandableList.tsx
+++ b/superset-frontend/src/components/ExpandableList.tsx
@@ -39,12 +39,12 @@ export default function ExpandableList({ items, display = 3
}: Props) {
const showMoreAction = items.length > display;
const lessAction = (
- <Button bsStyle="link" bsSize="xsmall" onClick={toggleShowingAll}>
+ <Button buttonStyle="link" buttonSize="xsmall" onClick={toggleShowingAll}>
less
</Button>
);
const moreAction = (
- <Button bsStyle="link" bsSize="xsmall" onClick={toggleShowingAll}>
+ <Button buttonStyle="link" buttonSize="xsmall" onClick={toggleShowingAll}>
{items.length - itemsToDisplay.length} more
</Button>
);
diff --git a/superset-frontend/src/components/Label/Label.stories.tsx
b/superset-frontend/src/components/Label/Label.stories.tsx
index 143e2c8..89b36e2 100644
--- a/superset-frontend/src/components/Label/Label.stories.tsx
+++ b/superset-frontend/src/components/Label/Label.stories.tsx
@@ -25,7 +25,7 @@ export default {
title: 'Label',
component: Label,
decorators: [withKnobs],
- excludeStories: ['bsStyleKnob'],
+ excludeStories: /.*Knob$/,
};
export const bsStyleKnob = {
diff --git a/superset-frontend/src/components/ListView/ListView.tsx
b/superset-frontend/src/components/ListView/ListView.tsx
index f825753..54fdeae 100644
--- a/superset-frontend/src/components/ListView/ListView.tsx
+++ b/superset-frontend/src/components/ListView/ListView.tsx
@@ -311,11 +311,12 @@ function ListView<T extends object = any>({
<Button
data-test="bulk-select-action"
key={action.key}
- className={cx('supersetButton', {
+ className={cx({
danger: action.type === 'danger',
primary: action.type === 'primary',
secondary: action.type === 'secondary',
})}
+ cta
onClick={() =>
action.onSelect(selectedFlatRows.map(r => r.original))
}
diff --git a/superset-frontend/src/components/Menu/Menu.tsx
b/superset-frontend/src/components/Menu/Menu.tsx
index 23da030..ef01b35 100644
--- a/superset-frontend/src/components/Menu/Menu.tsx
+++ b/superset-frontend/src/components/Menu/Menu.tsx
@@ -129,6 +129,14 @@ const StyledHeader = styled.header`
margin-bottom: 8px;
border-bottom: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
}
+ .navbar-right {
+ display: flex;
+ align-items: center;
+ .dropdown:first-of-type {
+ /* this is the "+ NEW" button. Sweep this up when it's replaced */
+ margin-right: ${({ theme }) => theme.gridUnit * 2}px;
+ }
+ }
`;
export function Menu({
diff --git a/superset-frontend/src/components/Menu/NewMenu.tsx
b/superset-frontend/src/components/Menu/NewMenu.tsx
index 055ca2e..5ac1fd2 100644
--- a/superset-frontend/src/components/Menu/NewMenu.tsx
+++ b/superset-frontend/src/components/Menu/NewMenu.tsx
@@ -17,15 +17,9 @@
* under the License.
*/
import React from 'react';
-import styled from '@superset-ui/style';
import { t } from '@superset-ui/translation';
import Button, { DropdownItemProps } from '../Button';
-const StyledButton = styled(Button)`
- margin-top: 12px;
- margin-right: 30px;
-`;
-
const dropdownItems: DropdownItemProps[] = [
{
label: t('SQL Query'),
@@ -47,12 +41,9 @@ const dropdownItems: DropdownItemProps[] = [
export default function NewMenu() {
return (
<li className="dropdown">
- <StyledButton
- className="dropdown-toggle btn btn-sm btn-primary"
- dropdownItems={dropdownItems}
- >
+ <Button buttonStyle="primary" dropdownItems={dropdownItems}>
<i className="fa fa-plus" /> New
- </StyledButton>
+ </Button>
</li>
);
}
diff --git a/superset-frontend/src/components/Menu/SubMenu.tsx
b/superset-frontend/src/components/Menu/SubMenu.tsx
index f3a27e9..1450001 100644
--- a/superset-frontend/src/components/Menu/SubMenu.tsx
+++ b/superset-frontend/src/components/Menu/SubMenu.tsx
@@ -26,12 +26,8 @@ const StyledHeader = styled.header`
font-weight: ${({ theme }) => theme.typography.weights.bold};
}
.navbar-right {
- .supersetButton {
- margin: ${({ theme }) =>
- `${theme.gridUnit * 2}px ${theme.gridUnit * 4}px ${
- theme.gridUnit * 2
- }px 0`};
- }
+ padding: 8px 0;
+ margin-right: 0;
}
.navbar-nav {
li {
@@ -94,16 +90,18 @@ const SubMenu: React.FunctionComponent<SubMenuProps> =
props => {
<Nav className="navbar-right">
{props.secondaryButton && (
<Button
- className="supersetButton secondary"
+ buttonStyle="secondary"
onClick={props.secondaryButton.onClick}
+ cta
>
{props.secondaryButton.name}
</Button>
)}
{props.primaryButton && (
<Button
- className="supersetButton primary"
+ buttonStyle="primary"
onClick={props.primaryButton.onClick}
+ cta
>
{props.primaryButton.name}
</Button>
diff --git a/superset-frontend/src/components/Modal.tsx
b/superset-frontend/src/components/Modal.tsx
index eed1215..0c179bb 100644
--- a/superset-frontend/src/components/Modal.tsx
+++ b/superset-frontend/src/components/Modal.tsx
@@ -20,7 +20,7 @@ import React from 'react';
import styled from '@superset-ui/style';
import { Modal as BaseModal } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import Button from 'src/views/CRUD/data/dataset/Button';
+import Button from 'src/components/Button';
interface ModalProps {
children: React.ReactNode;
@@ -54,9 +54,6 @@ const StyledModal = styled(BaseModal)`
.modal-footer {
border-top: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
padding: 16px;
- .btn + .btn {
- margin-left: 8px;
- }
}
`;
@@ -86,11 +83,14 @@ export default function Modal({
<BaseModal.Body>{children}</BaseModal.Body>
<BaseModal.Footer>
<span className="float-right">
- <Button onClick={onHide}>{t('Cancel')}</Button>
+ <Button onClick={onHide} cta>
+ {t('Cancel')}
+ </Button>
<Button
- bsStyle={primaryButtonType}
+ buttonStyle={primaryButtonType}
disabled={disablePrimaryButton}
onClick={onHandledPrimaryAction}
+ cta
>
{primaryButtonName}
</Button>
diff --git a/superset-frontend/src/components/ModalTrigger.jsx
b/superset-frontend/src/components/ModalTrigger.jsx
index 1a7ddd1..ea93080 100644
--- a/superset-frontend/src/components/ModalTrigger.jsx
+++ b/superset-frontend/src/components/ModalTrigger.jsx
@@ -19,9 +19,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, MenuItem } from 'react-bootstrap';
-import cx from 'classnames';
-import Button from './Button';
+import Button from 'src/components/Button';
const propTypes = {
dialogClassName: PropTypes.string,
@@ -96,9 +95,6 @@ export default class ModalTrigger extends React.Component {
}
render() {
- const classNames = cx({
- 'btn btn-default btn-sm': this.props.isButton,
- });
if (this.props.isButton) {
return (
<>
@@ -123,7 +119,7 @@ export default class ModalTrigger extends React.Component {
/* eslint-disable jsx-a11y/interactive-supports-focus */
return (
<>
- <span className={classNames} onClick={this.open} role="button">
+ <span onClick={this.open} role="button">
{this.props.triggerNode}
</span>
{this.renderModal()}
diff --git a/superset-frontend/src/components/RefreshChartOverlay.tsx
b/superset-frontend/src/components/RefreshChartOverlay.tsx
index 75cce63..26a0994 100644
--- a/superset-frontend/src/components/RefreshChartOverlay.tsx
+++ b/superset-frontend/src/components/RefreshChartOverlay.tsx
@@ -53,7 +53,7 @@ class RefreshChartOverlay extends React.PureComponent<Props> {
<Button
className="refresh-btn"
onClick={this.props.onQuery}
- bsStyle="primary"
+ buttonStyle="primary"
>
{t('Run Query')}
</Button>
diff --git
a/superset-frontend/src/dashboard/components/DeleteComponentModal.jsx
b/superset-frontend/src/dashboard/components/DeleteComponentModal.jsx
index 1d50017..5efcb79 100644
--- a/superset-frontend/src/dashboard/components/DeleteComponentModal.jsx
+++ b/superset-frontend/src/dashboard/components/DeleteComponentModal.jsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import ModalTrigger from '../../components/ModalTrigger';
@@ -66,7 +66,7 @@ export default class DeleteComponentModal extends
React.PureComponent {
</div>
<div className="dashboard-modal-actions-container">
<Button onClick={this.close}>{t('Cancel')}</Button>
- <Button bsStyle="primary" onClick={this.deleteTab}>
+ <Button buttonStyle="primary" onClick={this.deleteTab}>
{t('Delete')}
</Button>
</div>
diff --git a/superset-frontend/src/dashboard/components/Header.jsx
b/superset-frontend/src/dashboard/components/Header.jsx
index 89f2084..fa418b4 100644
--- a/superset-frontend/src/dashboard/components/Header.jsx
+++ b/superset-frontend/src/dashboard/components/Header.jsx
@@ -26,10 +26,10 @@ import { CategoricalColorNamespace } from
'@superset-ui/color';
import { t } from '@superset-ui/translation';
import Icon from 'src/components/Icon';
+import Button from 'src/components/Button';
import HeaderActionsDropdown from './HeaderActionsDropdown';
import EditableTitle from '../../components/EditableTitle';
-import Button from '../../components/Button';
import FaveStar from '../../components/FaveStar';
import PublishedStatus from './PublishedStatus';
import UndoRedoKeylisteners from './UndoRedoKeylisteners';
@@ -390,36 +390,40 @@ class Header extends React.PureComponent {
<>
<ButtonGroup className="m-r-5">
<Button
- bsSize="small"
+ buttonSize="small"
onClick={onUndo}
disabled={undoLength < 1}
- bsStyle={this.state.emphasizeUndo ? 'primary' :
undefined}
+ buttonStyle={
+ this.state.emphasizeUndo ? 'primary' : undefined
+ }
>
<i title="Undo" className="undo-action fa fa-reply" />
</Button>
<Button
- bsSize="small"
+ buttonSize="small"
onClick={onRedo}
disabled={redoLength < 1}
- bsStyle={this.state.emphasizeRedo ? 'primary' :
undefined}
+ buttonStyle={
+ this.state.emphasizeRedo ? 'primary' : undefined
+ }
>
<i title="Redo" className="redo-action fa fa-share" />
</Button>
</ButtonGroup>
<Button
- bsSize="small"
+ buttonSize="small"
className="m-r-5"
onClick={this.constructor.discardChanges}
- bsStyle="default"
+ buttonStyle="default"
>
{t('Discard Changes')}
</Button>
<Button
- bsSize="small"
+ buttonSize="small"
disabled={!hasUnsavedChanges}
- bsStyle="primary"
+ buttonStyle="primary"
onClick={this.overwriteDashboard}
>
{t('Save')}
diff --git a/superset-frontend/src/dashboard/components/PropertiesModal.jsx
b/superset-frontend/src/dashboard/components/PropertiesModal.jsx
index aac3be2..9f7fd2f 100644
--- a/superset-frontend/src/dashboard/components/PropertiesModal.jsx
+++ b/superset-frontend/src/dashboard/components/PropertiesModal.jsx
@@ -18,7 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Row, Col, Button, Modal, FormControl } from 'react-bootstrap';
+import { Row, Col, Modal, FormControl } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Dialog from 'react-bootstrap-dialog';
import { AsyncSelect } from 'src/components/Select';
import AceEditor from 'react-ace';
@@ -288,11 +289,7 @@ class PropertiesModal extends React.PureComponent {
<Row>
<Col md={12}>
<h3 style={{ marginTop: '1em' }}>
- <button
- type="button"
- className="text-button"
- onClick={this.toggleAdvanced}
- >
+ <Button buttonStyle="link" onClick={this.toggleAdvanced}>
<i
className={`fa fa-angle-${
isAdvancedOpen ? 'down' : 'right'
@@ -300,7 +297,7 @@ class PropertiesModal extends React.PureComponent {
style={{ minWidth: '1em' }}
/>
{t('Advanced')}
- </button>
+ </Button>
</h3>
{isAdvancedOpen && (
<>
@@ -332,14 +329,15 @@ class PropertiesModal extends React.PureComponent {
<span className="float-right">
<Button
type="submit"
- bsSize="sm"
- bsStyle="primary"
+ buttonSize="sm"
+ buttonStyle="primary"
className="m-r-5"
disabled={errors.length > 0}
+ cta
>
{saveLabel}
</Button>
- <Button type="button" bsSize="sm" onClick={onHide}>
+ <Button type="button" buttonSize="sm" onClick={onHide} cta>
{t('Cancel')}
</Button>
<Dialog
diff --git a/superset-frontend/src/dashboard/components/PublishedStatus.jsx
b/superset-frontend/src/dashboard/components/PublishedStatus.jsx
index cbf86d9..2bff312 100644
--- a/superset-frontend/src/dashboard/components/PublishedStatus.jsx
+++ b/superset-frontend/src/dashboard/components/PublishedStatus.jsx
@@ -19,7 +19,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { t } from '@superset-ui/translation';
-import TooltipWrapper from '../../components/TooltipWrapper';
+import TooltipWrapper from 'src/components/TooltipWrapper';
+import Label from 'src/components/Label';
const propTypes = {
dashboardId: PropTypes.number.isRequired,
@@ -43,14 +44,6 @@ const publishedTooltip = t(
'This dashboard is published. Click to make it a draft.',
);
-const divStyle = {
- border: '1px dotted black',
- backgroundColor: '#F9F9F9',
- padding: '3px 7px 3px 7px',
- fontFamily: 'Monospace',
- fontSize: '16px',
-};
-
export default class PublishedStatus extends React.Component {
componentDidMount() {
this.togglePublished = this.togglePublished.bind(this);
@@ -71,14 +64,13 @@ export default class PublishedStatus extends
React.Component {
placement="bottom"
tooltip={draftButtonTooltip}
>
- <button
- style={divStyle}
+ <Label
onClick={() => {
this.togglePublished();
}}
>
Draft
- </button>
+ </Label>
</TooltipWrapper>
);
}
@@ -88,7 +80,7 @@ export default class PublishedStatus extends React.Component {
placement="bottom"
tooltip={draftDivTooltip}
>
- <div style={divStyle}>Draft</div>
+ <Label>Draft</Label>
</TooltipWrapper>
);
}
@@ -101,14 +93,13 @@ export default class PublishedStatus extends
React.Component {
placement="bottom"
tooltip={publishedTooltip}
>
- <button
- style={divStyle}
+ <Label
onClick={() => {
this.togglePublished();
}}
>
Published
- </button>
+ </Label>
</TooltipWrapper>
);
}
diff --git
a/superset-frontend/src/dashboard/components/RefreshIntervalModal.jsx
b/superset-frontend/src/dashboard/components/RefreshIntervalModal.jsx
index c6957a3..7a00147 100644
--- a/superset-frontend/src/dashboard/components/RefreshIntervalModal.jsx
+++ b/superset-frontend/src/dashboard/components/RefreshIntervalModal.jsx
@@ -20,7 +20,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import Select from 'src/components/Select';
import { t } from '@superset-ui/translation';
-import { Alert, Button } from 'react-bootstrap';
+import { Alert } from 'react-bootstrap';
+import Button from 'src/components/Button';
import ModalTrigger from 'src/components/ModalTrigger';
import FormLabel from 'src/components/FormLabel';
@@ -116,10 +117,10 @@ class RefreshIntervalModal extends React.PureComponent {
}
modalFooter={
<>
- <Button bsStyle="primary" bsSize="sm" onClick={this.onSave}>
+ <Button buttonStyle="primary" buttonSize="sm"
onClick={this.onSave}>
{editMode ? t('Save') : t('Save for this session')}
</Button>
- <Button onClick={this.onCancel} bsSize="sm">
+ <Button onClick={this.onCancel} buttonSize="sm">
{t('Cancel')}
</Button>
</>
diff --git a/superset-frontend/src/dashboard/components/SaveModal.jsx
b/superset-frontend/src/dashboard/components/SaveModal.jsx
index 16a5d1e..7e8b87b 100644
--- a/superset-frontend/src/dashboard/components/SaveModal.jsx
+++ b/superset-frontend/src/dashboard/components/SaveModal.jsx
@@ -19,7 +19,8 @@
/* eslint-env browser */
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, FormControl, FormGroup, Radio } from 'react-bootstrap';
+import { FormControl, FormGroup, Radio } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { CategoricalColorNamespace } from '@superset-ui/color';
import { t } from '@superset-ui/translation';
@@ -191,7 +192,7 @@ class SaveModal extends React.PureComponent {
}
modalFooter={
<div>
- <Button bsStyle="primary" onClick={this.saveDashboard}>
+ <Button buttonStyle="primary" onClick={this.saveDashboard}>
{t('Save')}
</Button>
</div>
diff --git
a/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.jsx
b/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.jsx
index e3edd2b..204eb20 100644
---
a/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.jsx
+++
b/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.jsx
@@ -19,7 +19,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import buildFilterScopeTreeEntry from '../../util/buildFilterScopeTreeEntry';
@@ -513,11 +513,11 @@ export default class FilterScopeSelector extends
React.PureComponent {
</div>
<div className="dashboard-modal-actions-container">
- <Button bsSize="sm" onClick={this.onClose}>
+ <Button buttonSize="sm" onClick={this.onClose}>
{t('Close')}
</Button>
{showSelector && (
- <Button bsSize="sm" bsStyle="primary" onClick={this.onSave}>
+ <Button buttonSize="sm" buttonStyle="primary"
onClick={this.onSave}>
{t('Save')}
</Button>
)}
diff --git a/superset-frontend/src/dashboard/stylesheets/buttons.less
b/superset-frontend/src/dashboard/stylesheets/buttons.less
index f3527f7..9cec645 100644
--- a/superset-frontend/src/dashboard/stylesheets/buttons.less
+++ b/superset-frontend/src/dashboard/stylesheets/buttons.less
@@ -41,14 +41,3 @@
padding-left: 8px;
font-size: @font-size-m;
}
-
-.text-button {
- outline: none;
- border: none;
- margin: 0;
- padding: 0;
- background: none;
- text-decoration: none;
- font-size: inherit;
- font-weight: inherit;
-}
diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx
b/superset-frontend/src/datasource/DatasourceEditor.jsx
index 9f3d110..4a36b90 100644
--- a/superset-frontend/src/datasource/DatasourceEditor.jsx
+++ b/superset-frontend/src/datasource/DatasourceEditor.jsx
@@ -784,7 +784,7 @@ export class DatasourceEditor extends React.PureComponent {
}
/>
<Button
- bsStyle="primary"
+ buttonStyle="primary"
onClick={this.syncMetadata}
className="sync-from-source"
disabled={!!datasource.sql}
diff --git a/superset-frontend/src/datasource/DatasourceModal.tsx
b/superset-frontend/src/datasource/DatasourceModal.tsx
index eb33a32..6af23b6 100644
--- a/superset-frontend/src/datasource/DatasourceModal.tsx
+++ b/superset-frontend/src/datasource/DatasourceModal.tsx
@@ -17,7 +17,8 @@
* under the License.
*/
import React, { FunctionComponent, useState, useRef } from 'react';
-import { Alert, Button, Modal } from 'react-bootstrap';
+import { Alert, Modal } from 'react-bootstrap';
+import Button from 'src/components/Button';
// @ts-ignore
import Dialog from 'react-bootstrap-dialog';
import { t } from '@superset-ui/translation';
@@ -158,8 +159,8 @@ const DatasourceModal:
FunctionComponent<DatasourceModalProps> = ({
<Modal.Footer>
<span className="float-left">
<Button
- bsSize="sm"
- bsStyle="default"
+ buttonSize="sm"
+ buttonStyle="default"
target="_blank"
href={currentDatasource.edit_url || currentDatasource.url}
>
@@ -169,15 +170,16 @@ const DatasourceModal:
FunctionComponent<DatasourceModalProps> = ({
<span className="float-right">
<Button
- bsSize="sm"
- bsStyle="primary"
+ buttonSize="sm"
+ buttonStyle="primary"
className="m-r-5"
+ data-test="datasource-modal-save"
onClick={onClickSave}
disabled={errors.length > 0}
>
{t('Save')}
</Button>
- <Button bsSize="sm" onClick={onHide}>
+ <Button buttonSize="sm" onClick={onHide}>
{t('Cancel')}
</Button>
<Dialog ref={dialog} />
diff --git
a/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
b/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
index 7fc48b6..e28e118 100644
--- a/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
+++ b/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
@@ -18,7 +18,9 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Popover, Tab, Tabs } from 'react-bootstrap';
+import { Popover, Tab, Tabs } from 'react-bootstrap';
+import Button from 'src/components/Button';
+import { ThemeProvider } from '@superset-ui/style';
import columnType from '../propTypes/columnType';
import adhocMetricType from '../propTypes/adhocMetricType';
@@ -40,6 +42,7 @@ const propTypes = {
).isRequired,
datasource: PropTypes.object,
partitionColumn: PropTypes.string,
+ theme: PropTypes.object,
};
const startingWidth = 300;
@@ -119,6 +122,7 @@ export default class AdhocFilterEditPopover extends
React.Component {
onResize,
datasource,
partitionColumn,
+ theme,
...popoverProps
} = this.props;
@@ -129,68 +133,74 @@ export default class AdhocFilterEditPopover extends
React.Component {
return (
<Popover id="filter-edit-popover" {...popoverProps}>
- <Tabs
- id="adhoc-filter-edit-tabs"
- defaultActiveKey={adhocFilter.expressionType}
- className="adhoc-filter-edit-tabs"
- style={{ height: this.state.height, width: this.state.width }}
- >
- <Tab
- className="adhoc-filter-edit-tab"
- eventKey={EXPRESSION_TYPES.SIMPLE}
- title="Simple"
+ <ThemeProvider theme={theme}>
+ <Tabs
+ id="adhoc-filter-edit-tabs"
+ defaultActiveKey={adhocFilter.expressionType}
+ className="adhoc-filter-edit-tabs"
+ style={{ height: this.state.height, width: this.state.width }}
>
- <AdhocFilterEditPopoverSimpleTabContent
- adhocFilter={this.state.adhocFilter}
- onChange={this.onAdhocFilterChange}
- options={options}
- datasource={datasource}
- onHeightChange={this.adjustHeight}
- partitionColumn={partitionColumn}
- />
- </Tab>
- <Tab
- className="adhoc-filter-edit-tab"
- eventKey={EXPRESSION_TYPES.SQL}
- title="Custom SQL"
- >
- {!this.props.datasource ||
- this.props.datasource.type !== 'druid' ? (
- <AdhocFilterEditPopoverSqlTabContent
+ <Tab
+ className="adhoc-filter-edit-tab"
+ eventKey={EXPRESSION_TYPES.SIMPLE}
+ title="Simple"
+ >
+ <AdhocFilterEditPopoverSimpleTabContent
adhocFilter={this.state.adhocFilter}
onChange={this.onAdhocFilterChange}
- options={this.props.options}
- height={this.state.height}
+ options={options}
+ datasource={datasource}
+ onHeightChange={this.adjustHeight}
+ partitionColumn={partitionColumn}
/>
- ) : (
- <div className="custom-sql-disabled-message">
- Custom SQL Filters are not available on druid datasources
- </div>
- )}
- </Tab>
- </Tabs>
- <div>
- <Button
- disabled={!stateIsValid}
- bsStyle={hasUnsavedChanges && stateIsValid ? 'primary' : 'default'}
- bsSize="small"
- className="m-r-5"
- onClick={this.onSave}
- >
- Save
- </Button>
- <Button bsSize="small" onClick={this.props.onClose}>
- Close
- </Button>
- <i
- role="button"
- tabIndex={0}
- onMouseDown={this.onDragDown}
- className="fa fa-expand edit-popover-resize text-muted"
- />
- </div>
+ </Tab>
+ <Tab
+ className="adhoc-filter-edit-tab"
+ eventKey={EXPRESSION_TYPES.SQL}
+ title="Custom SQL"
+ >
+ {!this.props.datasource ||
+ this.props.datasource.type !== 'druid' ? (
+ <AdhocFilterEditPopoverSqlTabContent
+ adhocFilter={this.state.adhocFilter}
+ onChange={this.onAdhocFilterChange}
+ options={this.props.options}
+ height={this.state.height}
+ />
+ ) : (
+ <div className="custom-sql-disabled-message">
+ Custom SQL Filters are not available on druid datasources
+ </div>
+ )}
+ </Tab>
+ </Tabs>
+ <div>
+ <Button
+ disabled={!stateIsValid}
+ buttonStyle={
+ hasUnsavedChanges && stateIsValid ? 'primary' : 'default'
+ }
+ buttonSize="small"
+ className="m-r-5"
+ onClick={this.onSave}
+ cta
+ >
+ Save
+ </Button>
+ <Button buttonSize="small" onClick={this.props.onClose} cta>
+ Close
+ </Button>
+ <i
+ role="button"
+ tabIndex={0}
+ onMouseDown={this.onDragDown}
+ className="fa fa-expand edit-popover-resize text-muted"
+ />
+ </div>
+ </ThemeProvider>
</Popover>
);
}
}
+
AdhocFilterEditPopover.propTypes = propTypes;
diff --git a/superset-frontend/src/explore/components/AdhocFilterOption.jsx
b/superset-frontend/src/explore/components/AdhocFilterOption.jsx
index 7d05454..1ba5ef1 100644
--- a/superset-frontend/src/explore/components/AdhocFilterOption.jsx
+++ b/superset-frontend/src/explore/components/AdhocFilterOption.jsx
@@ -21,6 +21,7 @@ import PropTypes from 'prop-types';
import { OverlayTrigger } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
+import { withTheme } from '@superset-ui/style';
import Label from 'src/components/Label';
import AdhocFilterEditPopover from './AdhocFilterEditPopover';
@@ -41,8 +42,7 @@ const propTypes = {
datasource: PropTypes.object,
partitionColumn: PropTypes.string,
};
-
-export default class AdhocFilterOption extends React.PureComponent {
+class AdhocFilterOption extends React.PureComponent {
constructor(props) {
super(props);
this.closeFilterEditOverlay = this.closeFilterEditOverlay.bind(this);
@@ -73,7 +73,7 @@ export default class AdhocFilterOption extends
React.PureComponent {
}
render() {
- const { adhocFilter } = this.props;
+ const { adhocFilter, theme } = this.props;
const overlay = (
<AdhocFilterEditPopover
onResize={this.onPopoverResize}
@@ -83,6 +83,7 @@ export default class AdhocFilterOption extends
React.PureComponent {
options={this.props.options}
datasource={this.props.datasource}
partitionColumn={this.props.partitionColumn}
+ theme={theme}
/>
);
return (
@@ -123,4 +124,7 @@ export default class AdhocFilterOption extends
React.PureComponent {
);
}
}
+
+export default withTheme(AdhocFilterOption);
+
AdhocFilterOption.propTypes = propTypes;
diff --git
a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
index e94a7bb..4e8d577 100644
--- a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
+++ b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
@@ -18,7 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, FormGroup, Popover, Tab, Tabs } from 'react-bootstrap';
+import { FormGroup, Popover, Tab, Tabs } from 'react-bootstrap';
+import Button from 'src/components/Button';
import Select from 'src/components/Select';
import ace from 'brace';
import AceEditor from 'react-ace';
@@ -27,6 +28,7 @@ import 'brace/theme/github';
import 'brace/ext/language_tools';
import { t } from '@superset-ui/translation';
import { ColumnOption } from '@superset-ui/chart-controls';
+import { ThemeProvider } from '@superset-ui/style';
import FormLabel from 'src/components/FormLabel';
@@ -45,6 +47,7 @@ const propTypes = {
onResize: PropTypes.func.isRequired,
columns: PropTypes.arrayOf(columnType),
datasourceType: PropTypes.string,
+ theme: PropTypes.object,
};
const defaultProps = {
@@ -192,6 +195,7 @@ export default class AdhocMetricEditPopover extends
React.Component {
onClose,
onResize,
datasourceType,
+ theme,
...popoverProps
} = this.props;
@@ -232,98 +236,104 @@ export default class AdhocMetricEditPopover extends
React.Component {
const hasUnsavedChanges = !adhocMetric.equals(propsAdhocMetric);
return (
<Popover id="metrics-edit-popover" title={popoverTitle}
{...popoverProps}>
- <Tabs
- id="adhoc-metric-edit-tabs"
- defaultActiveKey={adhocMetric.expressionType}
- className="adhoc-metric-edit-tabs"
- style={{ height: this.state.height, width: this.state.width }}
- onSelect={this.refreshAceEditor}
- animation={false}
- >
- <Tab
- className="adhoc-metric-edit-tab"
- eventKey={EXPRESSION_TYPES.SIMPLE}
- title="Simple"
+ <ThemeProvider theme={theme}>
+ <Tabs
+ id="adhoc-metric-edit-tabs"
+ defaultActiveKey={adhocMetric.expressionType}
+ className="adhoc-metric-edit-tabs"
+ style={{ height: this.state.height, width: this.state.width }}
+ onSelect={this.refreshAceEditor}
+ animation={false}
>
- <FormGroup>
- <FormLabel>
- <strong>column</strong>
- </FormLabel>
- <Select
- name="select-column"
- {...this.selectProps}
- {...columnSelectProps}
- />
- </FormGroup>
- <FormGroup>
- <FormLabel>
- <strong>aggregate</strong>
- </FormLabel>
- <Select
- name="select-aggregate"
- {...this.selectProps}
- {...aggregateSelectProps}
- autoFocus
- />
- </FormGroup>
- </Tab>
- <Tab
- className="adhoc-metric-edit-tab"
- eventKey={EXPRESSION_TYPES.SQL}
- title="Custom SQL"
- data-test="adhoc-metric-edit-tab#custom"
- >
- {this.props.datasourceType !== 'druid' ? (
+ <Tab
+ className="adhoc-metric-edit-tab"
+ eventKey={EXPRESSION_TYPES.SIMPLE}
+ title="Simple"
+ >
<FormGroup>
- <AceEditor
- ref={this.handleAceEditorRef}
- mode="sql"
- theme="github"
- height={`${this.state.height - 43}px`}
- onChange={this.onSqlExpressionChange}
- width="100%"
- showGutter={false}
- value={
- adhocMetric.sqlExpression || adhocMetric.translateToSql()
- }
- editorProps={{ $blockScrolling: true }}
- enableLiveAutocompletion
- className="adhoc-filter-sql-editor"
- wrapEnabled
+ <FormLabel>
+ <strong>column</strong>
+ </FormLabel>
+ <Select
+ name="select-column"
+ {...this.selectProps}
+ {...columnSelectProps}
/>
</FormGroup>
- ) : (
- <div className="custom-sql-disabled-message">
- Custom SQL Metrics are not available on druid datasources
- </div>
- )}
- </Tab>
- </Tabs>
- <div>
- <Button
- disabled={!stateIsValid}
- 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}
- data-test="AdhocMetricEdit#cancel"
- >
- Close
- </Button>
- <i
- role="button"
- tabIndex={0}
- onMouseDown={this.onDragDown}
- className="fa fa-expand edit-popover-resize text-muted"
- />
- </div>
+ <FormGroup>
+ <FormLabel>
+ <strong>aggregate</strong>
+ </FormLabel>
+ <Select
+ name="select-aggregate"
+ {...this.selectProps}
+ {...aggregateSelectProps}
+ autoFocus
+ />
+ </FormGroup>
+ </Tab>
+ <Tab
+ className="adhoc-metric-edit-tab"
+ eventKey={EXPRESSION_TYPES.SQL}
+ title="Custom SQL"
+ data-test="adhoc-metric-edit-tab#custom"
+ >
+ {this.props.datasourceType !== 'druid' ? (
+ <FormGroup>
+ <AceEditor
+ ref={this.handleAceEditorRef}
+ mode="sql"
+ theme="github"
+ height={`${this.state.height - 43}px`}
+ onChange={this.onSqlExpressionChange}
+ width="100%"
+ showGutter={false}
+ value={
+ adhocMetric.sqlExpression || adhocMetric.translateToSql()
+ }
+ editorProps={{ $blockScrolling: true }}
+ enableLiveAutocompletion
+ className="adhoc-filter-sql-editor"
+ wrapEnabled
+ />
+ </FormGroup>
+ ) : (
+ <div className="custom-sql-disabled-message">
+ Custom SQL Metrics are not available on druid datasources
+ </div>
+ )}
+ </Tab>
+ </Tabs>
+ <div>
+ <Button
+ disabled={!stateIsValid}
+ buttonStyle={
+ hasUnsavedChanges && stateIsValid ? 'primary' : 'default'
+ }
+ buttonSize="small"
+ className="m-r-5"
+ data-test="AdhocMetricEdit#save"
+ onClick={this.onSave}
+ cta
+ >
+ Save
+ </Button>
+ <Button
+ buttonSize="small"
+ onClick={this.props.onClose}
+ data-test="AdhocMetricEdit#cancel"
+ cta
+ >
+ Close
+ </Button>
+ <i
+ role="button"
+ tabIndex={0}
+ onMouseDown={this.onDragDown}
+ className="fa fa-expand edit-popover-resize text-muted"
+ />
+ </div>
+ </ThemeProvider>
</Popover>
);
}
diff --git a/superset-frontend/src/explore/components/AdhocMetricOption.jsx
b/superset-frontend/src/explore/components/AdhocMetricOption.jsx
index 945107c..7d84697 100644
--- a/superset-frontend/src/explore/components/AdhocMetricOption.jsx
+++ b/superset-frontend/src/explore/components/AdhocMetricOption.jsx
@@ -19,6 +19,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { OverlayTrigger } from 'react-bootstrap';
+import { withTheme } from '@superset-ui/style';
import Label from 'src/components/Label';
import AdhocMetricEditPopover from './AdhocMetricEditPopover';
@@ -33,7 +34,7 @@ const propTypes = {
datasourceType: PropTypes.string,
};
-export default class AdhocMetricOption extends React.PureComponent {
+class AdhocMetricOption extends React.PureComponent {
constructor(props) {
super(props);
this.closeMetricEditOverlay = this.closeMetricEditOverlay.bind(this);
@@ -65,7 +66,7 @@ export default class AdhocMetricOption extends
React.PureComponent {
}
render() {
- const { adhocMetric } = this.props;
+ const { adhocMetric, theme } = this.props;
const overlayContent = (
<AdhocMetricEditPopover
onResize={this.onPopoverResize}
@@ -74,6 +75,7 @@ export default class AdhocMetricOption extends
React.PureComponent {
onClose={this.closeMetricEditOverlay}
columns={this.props.columns}
datasourceType={this.props.datasourceType}
+ theme={theme}
/>
);
@@ -109,4 +111,7 @@ export default class AdhocMetricOption extends
React.PureComponent {
);
}
}
+
+export default withTheme(AdhocMetricOption);
+
AdhocMetricOption.propTypes = propTypes;
diff --git a/superset-frontend/src/explore/components/DisplayQueryButton.jsx
b/superset-frontend/src/explore/components/DisplayQueryButton.jsx
index aa41f11..495bf61 100644
--- a/superset-frontend/src/explore/components/DisplayQueryButton.jsx
+++ b/superset-frontend/src/explore/components/DisplayQueryButton.jsx
@@ -38,13 +38,13 @@ import {
import { Table } from 'reactable-arc';
import { t } from '@superset-ui/translation';
+import Button from 'src/components/Button';
import getClientErrorObject from '../../utils/getClientErrorObject';
import CopyToClipboard from './../../components/CopyToClipboard';
import { getChartDataRequest } from '../../chart/chartAction';
import downloadAsImage from '../../utils/downloadAsImage';
import Loading from '../../components/Loading';
import ModalTrigger from './../../components/ModalTrigger';
-import Button from '../../components/Button';
import RowCountLabel from './RowCountLabel';
import {
applyFormattingToTabularData,
diff --git a/superset-frontend/src/explore/components/ExploreActionButtons.jsx
b/superset-frontend/src/explore/components/ExploreActionButtons.jsx
index 08757fe..7b45d9d 100644
--- a/superset-frontend/src/explore/components/ExploreActionButtons.jsx
+++ b/superset-frontend/src/explore/components/ExploreActionButtons.jsx
@@ -47,7 +47,7 @@ export default function ExploreActionButtons({
slice,
}) {
const exportToCSVClasses = cx('btn btn-default btn-sm', {
- 'disabled disabledButton': !canDownload,
+ disabled: !canDownload,
});
const doExportCSV = exportChart.bind(this, {
formData: latestQueryFormData,
diff --git a/superset-frontend/src/explore/components/PropertiesModal.tsx
b/superset-frontend/src/explore/components/PropertiesModal.tsx
index bbcb508..8b5d76d 100644
--- a/superset-frontend/src/explore/components/PropertiesModal.tsx
+++ b/superset-frontend/src/explore/components/PropertiesModal.tsx
@@ -18,7 +18,6 @@
*/
import React, { useState, useEffect, useRef } from 'react';
import {
- Button,
Modal,
Row,
Col,
@@ -26,6 +25,7 @@ import {
FormGroup,
// @ts-ignore
} from 'react-bootstrap';
+import Button from 'src/components/Button';
// @ts-ignore
import Dialog from 'react-bootstrap-dialog';
import { OptionsType } from 'react-select/src/types';
@@ -263,15 +263,15 @@ function PropertiesModal({ slice, onHide, onSave }:
InternalProps) {
</Row>
</Modal.Body>
<Modal.Footer>
- <Button type="button" bsSize="sm" onClick={onHide}>
+ <Button type="button" buttonSize="sm" onClick={onHide} cta>
{t('Cancel')}
</Button>
<Button
type="submit"
- bsSize="sm"
- bsStyle="primary"
- className="m-r-5"
+ buttonSize="sm"
+ buttonStyle="primary"
disabled={!owners || submitting || !name}
+ cta
>
{t('Save')}
</Button>
diff --git a/superset-frontend/src/explore/components/QueryAndSaveBtns.jsx
b/superset-frontend/src/explore/components/QueryAndSaveBtns.jsx
index a8bba79..d39fa6a 100644
--- a/superset-frontend/src/explore/components/QueryAndSaveBtns.jsx
+++ b/superset-frontend/src/explore/components/QueryAndSaveBtns.jsx
@@ -19,11 +19,10 @@
import React from 'react';
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 Button from 'src/components/Button';
import Hotkeys from '../../components/Hotkeys';
const propTypes = {
@@ -61,7 +60,8 @@ const Styles = styled.div`
align-items: center;
padding-bottom: ${({ theme }) => 2 * theme.gridUnit}px;
- .save-btn {
+ .btn {
+ /* just to make sure buttons don't jiggle */
width: 100px;
}
`;
@@ -75,12 +75,7 @@ export default function QueryAndSaveBtns({
chartIsStale,
errorMessage,
}) {
- const saveClasses = classnames({
- 'disabled disabledButton': !canAdd,
- 'save-btn': true,
- });
-
- let qryButtonStyle = 'default';
+ let qryButtonStyle = 'secondary';
if (errorMessage) {
qryButtonStyle = 'danger';
} else if (chartIsStale) {
@@ -89,15 +84,21 @@ export default function QueryAndSaveBtns({
const saveButtonDisabled = errorMessage ? true : loading;
const qryOrStopButton = loading ? (
- <Button onClick={onStop} bsStyle="warning" className="save-btn">
+ <Button
+ onClick={onStop}
+ buttonStyle="warning"
+ buttonSize="small"
+ disabled={!canAdd}
+ >
<i className="fa fa-stop-circle-o" /> Stop
</Button>
) : (
<Button
- className="query save-btn"
+ buttonSize="small"
onClick={onQuery}
- bsStyle={qryButtonStyle}
+ buttonStyle={qryButtonStyle}
disabled={!!errorMessage}
+ data-test="run-query-button"
>
<i className="fa fa-bolt" /> {t('Run')}
</Button>
@@ -109,7 +110,8 @@ export default function QueryAndSaveBtns({
<ButtonGroup className="query-and-save">
{qryOrStopButton}
<Button
- className={saveClasses}
+ buttonStyle="secondary"
+ buttonSize="small"
data-target="#save_modal"
data-toggle="modal"
disabled={saveButtonDisabled}
diff --git a/superset-frontend/src/explore/components/SaveModal.jsx
b/superset-frontend/src/explore/components/SaveModal.jsx
index 804ebc2..e57189b 100644
--- a/superset-frontend/src/explore/components/SaveModal.jsx
+++ b/superset-frontend/src/explore/components/SaveModal.jsx
@@ -20,14 +20,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
-import {
- Alert,
- Button,
- FormControl,
- FormGroup,
- Modal,
- Radio,
-} from 'react-bootstrap';
+import { Alert, FormControl, FormGroup, Modal, Radio } from 'react-bootstrap';
+import Button from 'src/components/Button';
import FormLabel from 'src/components/FormLabel';
import { CreatableSelect } from 'src/components/Select/SupersetStyledSelect';
import { t } from '@superset-ui/translation';
@@ -208,18 +202,12 @@ class SaveModal extends React.Component {
<Modal.Footer>
<div className="float-right">
- <Button
- type="button"
- id="btn_cancel"
- bsSize="sm"
- onClick={this.props.onHide}
- >
+ <Button id="btn_cancel" buttonSize="sm"
onClick={this.props.onHide}>
{t('Cancel')}
</Button>
<Button
- type="button"
id="btn_modal_save_goto_dash"
- bsSize="sm"
+ buttonSize="sm"
disabled={
!this.state.newSliceName || !this.state.newDashboardName
}
@@ -228,10 +216,9 @@ class SaveModal extends React.Component {
{t('Save & go to dashboard')}
</Button>
<Button
- type="button"
id="btn_modal_save"
- bsSize="sm"
- bsStyle="primary"
+ buttonSize="sm"
+ buttonStyle="primary"
onClick={this.saveOrOverwrite.bind(this, false)}
disabled={!this.state.newSliceName}
>
diff --git
a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
index e119e87..d90cdd1 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
@@ -19,13 +19,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { CompactPicker } from 'react-color';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import mathjs from 'mathjs';
import { t } from '@superset-ui/translation';
import { SupersetClient } from '@superset-ui/connection';
import { getCategoricalSchemeRegistry } from '@superset-ui/color';
import { getChartMetadataRegistry } from '@superset-ui/chart';
import { validateNonEmpty } from '@superset-ui/validator';
+import { ThemeProvider } from '@superset-ui/style';
import SelectControl from './SelectControl';
import TextControl from './TextControl';
@@ -63,6 +64,7 @@ const propTypes = {
timeColumn: PropTypes.string,
intervalEndColumn: PropTypes.string,
vizType: PropTypes.string,
+ theme: PropTypes.object,
error: PropTypes.string,
colorScheme: PropTypes.string,
@@ -619,8 +621,8 @@ export default class AnnotationLayer extends
React.PureComponent {
/>
<Button
style={{ marginTop: '0.5rem', marginBottom: '0.5rem' }}
- bsStyle={color === AUTOMATIC_COLOR ? 'success' : 'default'}
- bsSize="xsmall"
+ buttonStyle={color === AUTOMATIC_COLOR ? 'success' : 'default'}
+ buttonSize="xsmall"
onClick={() => this.setState({ color: AUTOMATIC_COLOR })}
>
Automatic Color
@@ -661,7 +663,7 @@ export default class AnnotationLayer extends
React.PureComponent {
render() {
const { isNew, name, annotationType, sourceType, show } = this.state;
const isValid = this.isValidForm();
-
+ const { theme } = this.props;
const metadata = getChartMetadataRegistry().get(this.props.vizType);
const supportedAnnotationTypes = metadata
? metadata.supportedAnnotationTypes.map(
@@ -671,7 +673,7 @@ export default class AnnotationLayer extends
React.PureComponent {
const supportedSourceTypes = this.getSupportedSourceTypes(annotationType);
return (
- <div>
+ <ThemeProvider theme={theme}>
{this.props.error && (
<span style={{ color: 'red' }}>ERROR: {this.props.error}</span>
)}
@@ -724,12 +726,12 @@ export default class AnnotationLayer extends
React.PureComponent {
{this.renderDisplayConfiguration()}
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <Button bsSize="sm" onClick={this.deleteAnnotation}>
+ <Button buttonSize="sm" onClick={this.deleteAnnotation}>
{!isNew ? t('Remove') : t('Cancel')}
</Button>
<div>
<Button
- bsSize="sm"
+ buttonSize="sm"
disabled={!isValid}
onClick={this.applyAnnotation}
>
@@ -737,7 +739,7 @@ export default class AnnotationLayer extends
React.PureComponent {
</Button>
<Button
- bsSize="sm"
+ buttonSize="sm"
disabled={!isValid}
onClick={this.submitAnnotation}
>
@@ -745,7 +747,7 @@ export default class AnnotationLayer extends
React.PureComponent {
</Button>
</div>
</div>
- </div>
+ </ThemeProvider>
);
}
}
diff --git
a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
index d0b5229..3eb594c 100644
---
a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
+++
b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
@@ -26,6 +26,7 @@ import {
} from 'react-bootstrap';
import { connect } from 'react-redux';
import { t } from '@superset-ui/translation';
+import { withTheme } from '@superset-ui/style';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { getChartKey } from '../../exploreUtils';
import { runAnnotationQuery } from '../../../chart/chartAction';
@@ -100,6 +101,7 @@ class AnnotationLayerControl extends React.PureComponent {
renderPopover(parent, annotation, error) {
const id = !annotation ? '_new' : annotation.name;
+ const { theme } = this.props;
return (
<Popover
style={{ maxWidth: 'none' }}
@@ -116,6 +118,7 @@ class AnnotationLayerControl extends React.PureComponent {
addAnnotationLayer={this.addAnnotationLayer}
removeAnnotationLayer={this.removeAnnotationLayer}
close={() => this.refs[parent].hide()}
+ theme={theme}
/>
</Popover>
);
@@ -208,7 +211,9 @@ function mapDispatchToProps(dispatch) {
};
}
+const themedAnnotationLayerControl = withTheme(AnnotationLayerControl);
+
export default connect(
mapStateToProps,
mapDispatchToProps,
-)(AnnotationLayerControl);
+)(themedAnnotationLayerControl);
diff --git
a/superset-frontend/src/explore/components/controls/DateFilterControl.jsx
b/superset-frontend/src/explore/components/controls/DateFilterControl.jsx
index 538123c..8e02c60 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl.jsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl.jsx
@@ -19,7 +19,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
- Button,
DropdownButton,
FormControl,
FormGroup,
@@ -32,6 +31,7 @@ import {
Tabs,
Tooltip,
} from 'react-bootstrap';
+import Button from 'src/components/Button';
import Datetime from 'react-datetime';
import 'react-datetime/css/react-datetime.css';
import moment from 'moment';
@@ -365,7 +365,7 @@ class DateFilterControl extends React.Component {
onClick={() => {}}
/>
<InputGroup.Button onClick={() => this.toggleCalendar(key)}>
- <Button>
+ <Button theme={this.props.theme}>
<i className="fa fa-calendar" />
</Button>
</InputGroup.Button>
@@ -563,10 +563,11 @@ class DateFilterControl extends React.Component {
</Tabs>
<div className="clearfix">
<Button
- bsSize="small"
+ buttonSize="small"
className="float-right ok"
- bsStyle="primary"
+ buttonStyle="primary"
onClick={this.close}
+ theme={this.props.theme}
>
Ok
</Button>
diff --git
a/superset-frontend/src/explore/components/controls/SpatialControl.jsx
b/superset-frontend/src/explore/components/controls/SpatialControl.jsx
index f9cdecb..4bef1b2 100644
--- a/superset-frontend/src/explore/components/controls/SpatialControl.jsx
+++ b/superset-frontend/src/explore/components/controls/SpatialControl.jsx
@@ -18,7 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Row, Col, Button, OverlayTrigger, Popover } from 'react-bootstrap';
+import { Row, Col, OverlayTrigger, Popover } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import Label from 'src/components/Label';
@@ -204,9 +205,9 @@ export default class SpatialControl extends React.Component
{
</PopoverSection>
<div className="clearfix">
<Button
- bsSize="small"
+ buttonSize="small"
className="float-left ok"
- bsStyle="primary"
+ buttonStyle="primary"
onClick={this.close.bind(this)}
>
Ok
diff --git
a/superset-frontend/src/explore/components/controls/TextAreaControl.jsx
b/superset-frontend/src/explore/components/controls/TextAreaControl.jsx
index 4cb607b..0a09f93 100644
--- a/superset-frontend/src/explore/components/controls/TextAreaControl.jsx
+++ b/superset-frontend/src/explore/components/controls/TextAreaControl.jsx
@@ -18,7 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, FormGroup, FormControl } from 'react-bootstrap';
+import { FormGroup, FormControl } from 'react-bootstrap';
+import Button from 'src/components/Button';
import AceEditor from 'react-ace';
import 'brace/mode/sql';
@@ -121,7 +122,7 @@ export default class TextAreaControl extends
React.Component {
bsSize="large"
modalTitle={controlHeader}
triggerNode={
- <Button bsSize="small" className="m-t-5">
+ <Button buttonSize="small" className="m-t-5">
{t('Edit')} <strong>{this.props.language}</strong>{' '}
{t('in modal')}
</Button>
diff --git a/superset-frontend/src/views/CRUD/data/dataset/Button.tsx
b/superset-frontend/src/views/CRUD/data/dataset/Button.tsx
deleted file mode 100644
index f0125e9..0000000
--- a/superset-frontend/src/views/CRUD/data/dataset/Button.tsx
+++ /dev/null
@@ -1,72 +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 React from 'react';
-import styled from '@superset-ui/style';
-import BaseButton from 'src/components/Button';
-
-interface ModalProps {
- children: React.ReactNode;
- disabled?: boolean;
- onClick: () => void;
- padding?: number;
- bsStyle?: 'default' | 'primary' | 'danger';
- width?: number;
-}
-
-const StyledButton = styled(BaseButton)`
- border-radius: ${({ theme }) => theme.borderRadius}px;
- border: none;
- padding: ${(props: ModalProps) => props.padding || 8}px;
- text-transform: uppercase;
- width: ${(props: ModalProps) => props.width || 160}px;
-
- &.btn,
- &.btn:hover {
- background-color: ${({ theme }) => theme.colors.primary.light4};
- color: ${({ theme }) => theme.colors.primary.base};
- }
- &.btn[disabled],
- &.btn[disabled]:hover {
- background-color: ${({ theme }) => theme.colors.grayscale.light2};
- color: ${({ theme }) => theme.colors.grayscale.light1};
- }
- &.btn-primary,
- &.btn-primary:hover {
- background-color: ${({ theme }) => theme.colors.primary.base};
- color: ${({ theme }) => theme.colors.grayscale.light5};
- }
- &.btn-danger,
- &.btn-danger:hover {
- background-color: ${({ theme }) => theme.colors.error.base};
- color: ${({ theme }) => theme.colors.grayscale.light5};
- }
-`;
-
-export default function Modal({
- bsStyle = 'default',
- disabled,
- onClick,
- children,
-}: ModalProps) {
- return (
- <StyledButton disabled={disabled} bsStyle={bsStyle} onClick={onClick}>
- {children}
- </StyledButton>
- );
-}
diff --git a/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx
b/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx
index 66b4fbe..f799430 100644
--- a/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx
+++ b/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx
@@ -21,7 +21,7 @@ import PropTypes from 'prop-types';
import { debounce } from 'lodash';
import { max as d3Max } from 'd3-array';
import { AsyncCreatableSelect, CreatableSelect } from 'src/components/Select';
-import { Button } from 'react-bootstrap';
+import Button from 'src/components/Button';
import { t } from '@superset-ui/translation';
import { SupersetClient } from '@superset-ui/connection';
import styled from '@superset-ui/style';
@@ -438,8 +438,8 @@ class FilterBox extends React.Component {
{this.renderFilters()}
{!instantFiltering && (
<Button
- bsSize="small"
- bsStyle="primary"
+ buttonSize="small"
+ buttonStyle="primary"
onClick={this.clickApply.bind(this)}
disabled={!this.state.hasChanged}
>
diff --git a/superset-frontend/stylesheets/superset.less
b/superset-frontend/stylesheets/superset.less
index 1560d67..6a06c92 100644
--- a/superset-frontend/stylesheets/superset.less
+++ b/superset-frontend/stylesheets/superset.less
@@ -196,6 +196,10 @@ table.table-no-hover tr:hover {
background-color: initial;
}
+.editable-title {
+ margin-right: 8px;
+}
+
.editable-title input {
outline: none;
background: transparent;
diff --git a/superset/assets/src/SqlLab/components/ExploreCtasResultsButton.jsx
b/superset/assets/src/SqlLab/components/ExploreCtasResultsButton.jsx
index f4b5e6f..a0601a1 100644
--- a/superset/assets/src/SqlLab/components/ExploreCtasResultsButton.jsx
+++ b/superset/assets/src/SqlLab/components/ExploreCtasResultsButton.jsx
@@ -26,7 +26,7 @@ import { InfoTooltipWithTrigger } from
'@superset-ui/chart-controls';
import { exploreChart } from '../../explore/exploreUtils';
import * as actions from '../actions/sqlLab';
-import Button from '../../components/Button';
+import Button from 'src/components/Button';
const propTypes = {
actions: PropTypes.object.isRequired,
@@ -88,7 +88,7 @@ class ExploreCtasResultsButton extends React.PureComponent {
return (
<>
<Button
- bsSize="small"
+ buttonSize="small"
onClick={this.onClick}
tooltip={t('Explore the result set in the data exploration view')}
>