mirror of
https://github.com/apache/superset.git
synced 2024-09-12 16:49:40 -04:00
refactor: Use Antd Modals instead of react-bootstrap Modals (#11366)
* Make Modal responsive * ErrorAlert * OmniContainer * dashboard/PropertiesModal * Fix e2e tests * Lint fix * E2E test fix * Fix test * Use grid units * Change padding to padding-left/right
This commit is contained in:
parent
a99d795eaf
commit
155b5edec1
@ -87,19 +87,19 @@ describe('Dashboard edit action', () => {
|
||||
const dashboardTitle = `Test dashboard [${shortid.generate()}]`;
|
||||
|
||||
// update title
|
||||
cy.get('.modal-body')
|
||||
cy.get('.ant-modal-body')
|
||||
.should('be.visible')
|
||||
.contains('Title')
|
||||
.siblings('input')
|
||||
.type(`{selectall}{backspace}${dashboardTitle}`);
|
||||
|
||||
// save edit changes
|
||||
cy.get('.modal-footer')
|
||||
cy.get('.ant-modal-footer')
|
||||
.contains('Save')
|
||||
.click()
|
||||
.then(() => {
|
||||
// assert that modal edit window has closed
|
||||
cy.get('.modal-body').should('not.exist');
|
||||
cy.get('.ant-modal-body').should('not.exist');
|
||||
|
||||
// assert title has been updated
|
||||
cy.get('.editable-title input').should('have.value', dashboardTitle);
|
||||
|
@ -90,7 +90,7 @@ describe('Dashboard save action', () => {
|
||||
openDashboardEditProperties();
|
||||
|
||||
// open color scheme dropdown
|
||||
cy.get('.modal-body')
|
||||
cy.get('.ant-modal-body')
|
||||
.contains('Color Scheme')
|
||||
.parents('.ControlHeader')
|
||||
.next('.Select')
|
||||
@ -105,7 +105,7 @@ describe('Dashboard save action', () => {
|
||||
});
|
||||
|
||||
// remove json metadata
|
||||
cy.get('.modal-body')
|
||||
cy.get('.ant-modal-body')
|
||||
.contains('Advanced')
|
||||
.click()
|
||||
.then(() => {
|
||||
@ -113,18 +113,18 @@ describe('Dashboard save action', () => {
|
||||
});
|
||||
|
||||
// update title
|
||||
cy.get('.modal-body')
|
||||
cy.get('.ant-modal-body')
|
||||
.contains('Title')
|
||||
.siblings('input')
|
||||
.type(`{selectall}{backspace}${dashboardTitle}`);
|
||||
|
||||
// save edit changes
|
||||
cy.get('.modal-footer')
|
||||
cy.get('.ant-modal-footer')
|
||||
.contains('Save')
|
||||
.click()
|
||||
.then(() => {
|
||||
// assert that modal edit window has closed
|
||||
cy.get('.modal-body').should('not.exist');
|
||||
cy.get('.ant-modal-body').should('not.exist');
|
||||
|
||||
// save dashboard changes
|
||||
cy.get('.dashboard-header').contains('Save').click();
|
||||
|
@ -101,11 +101,9 @@ describe('Dashboard card view', () => {
|
||||
cy.get('.ant-dropdown-trigger').last().trigger('mouseover');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Edit').should('exist');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Edit').click();
|
||||
cy.get('.modal-dialog').should('be.visible');
|
||||
cy.get('.modal-dialog input[name="dashboard_title"]').should(
|
||||
'not.have.value',
|
||||
);
|
||||
cy.get('.modal-dialog input[name="slug"]').should('not.have.value');
|
||||
cy.get('.modal-dialog .btn-default').contains('Cancel').click();
|
||||
cy.get('.ant-modal').should('be.visible');
|
||||
cy.get('.ant-modal input[name="dashboard_title"]').should('not.have.value');
|
||||
cy.get('.ant-modal input[name="slug"]').should('not.have.value');
|
||||
cy.get('.ant-modal .btn-default').contains('Cancel').click();
|
||||
});
|
||||
});
|
||||
|
@ -47,10 +47,12 @@ interface StyledModalProps extends SupersetThemeProps {
|
||||
}
|
||||
|
||||
const StyledModal = styled(BaseModal)<StyledModalProps>`
|
||||
${({ responsive, maxWidth }) =>
|
||||
${({ theme, responsive, maxWidth }) =>
|
||||
responsive &&
|
||||
css`
|
||||
max-width: ${maxWidth ?? '900px'};
|
||||
padding-left: ${theme.gridUnit * 3}px;
|
||||
padding-right: ${theme.gridUnit * 3}px;
|
||||
`}
|
||||
|
||||
.ant-modal-header {
|
||||
@ -137,7 +139,7 @@ export default function Modal({
|
||||
]
|
||||
: footer;
|
||||
|
||||
const modalWidth = width || responsive ? 'calc(100vw - 24px)' : '600px';
|
||||
const modalWidth = width || (responsive ? '100vw' : '600px');
|
||||
return (
|
||||
<StyledModal
|
||||
centered={!!centered}
|
||||
@ -154,6 +156,7 @@ export default function Modal({
|
||||
</span>
|
||||
}
|
||||
footer={!hideFooter ? modalFooter : null}
|
||||
data-test={`${title}-modal`}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
20
superset-frontend/src/common/components/Modal/index.ts
Normal file
20
superset-frontend/src/common/components/Modal/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
export * from './Modal';
|
||||
export { default } from './Modal';
|
@ -17,9 +17,9 @@
|
||||
* under the License.
|
||||
*/
|
||||
import React, { useState, ReactNode } from 'react';
|
||||
import { Modal } from 'react-bootstrap';
|
||||
import { styled, supersetTheme, t } from '@superset-ui/core';
|
||||
import { noOp } from 'src/utils/common';
|
||||
import Modal from 'src/common/components/Modal';
|
||||
import Button from 'src/components/Button';
|
||||
|
||||
import Icon from '../Icon';
|
||||
@ -64,17 +64,10 @@ const ErrorModal = styled(Modal)<{ level: ErrorLevel }>`
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: ${({ level, theme }) => theme.colors[level].light2};
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: ${({ theme }) => theme.typography.sizes.l}px;
|
||||
|
||||
// Remove clearfix hack as Superset is only used on modern browsers
|
||||
::before,
|
||||
::after {
|
||||
content: unset;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -157,30 +150,18 @@ export default function ErrorAlert({
|
||||
level={level}
|
||||
show={isModalOpen}
|
||||
onHide={() => setIsModalOpen(false)}
|
||||
>
|
||||
<Modal.Header className="header">
|
||||
<LeftSideContent>
|
||||
title={
|
||||
<div className="header">
|
||||
<Icon
|
||||
className="icon"
|
||||
name={level === 'error' ? 'error-solid' : 'warning-solid'}
|
||||
color={supersetTheme.colors[level].base}
|
||||
/>
|
||||
<div className="title">{title}</div>
|
||||
</LeftSideContent>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => setIsModalOpen(false)}
|
||||
>
|
||||
<Icon name="close" />
|
||||
</span>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<p>{subtitle}</p>
|
||||
<br />
|
||||
{body}
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
<>
|
||||
{copyText && (
|
||||
<CopyToClipboard
|
||||
text={copyText}
|
||||
@ -196,7 +177,14 @@ export default function ErrorAlert({
|
||||
>
|
||||
{t('Close')}
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<>
|
||||
<p>{subtitle}</p>
|
||||
<br />
|
||||
{body}
|
||||
</>
|
||||
</ErrorModal>
|
||||
)}
|
||||
</ErrorAlertDiv>
|
||||
|
@ -17,11 +17,11 @@
|
||||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Modal } from 'react-bootstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import { t, SupersetClient } from '@superset-ui/core';
|
||||
import { styled, t, SupersetClient } from '@superset-ui/core';
|
||||
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
|
||||
import Omnibar from 'omnibar';
|
||||
import Modal from 'src/common/components/Modal';
|
||||
import { LOG_ACTIONS_OMNIBAR_TRIGGERED } from '../logger/LogUtils';
|
||||
|
||||
const propTypes = {
|
||||
@ -44,6 +44,14 @@ const getDashboards = query =>
|
||||
title: t('An error occurred while fethching Dashboards'),
|
||||
}));
|
||||
|
||||
const OmniModal = styled(Modal)`
|
||||
margin-top: 20%;
|
||||
|
||||
.ant-modal-body {
|
||||
padding: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
class OmniContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -79,13 +87,13 @@ class OmniContainer extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal show={this.state.showOmni} style={{ marginTop: '25%' }}>
|
||||
<OmniModal show={this.state.showOmni} hideFooter closable={false}>
|
||||
<Omnibar
|
||||
className="Omnibar"
|
||||
placeholder="Search all dashboards"
|
||||
extensions={[getDashboards]}
|
||||
/>
|
||||
</Modal>
|
||||
</OmniModal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Row, Col, Modal, FormControl } from 'react-bootstrap';
|
||||
import { Row, Col, FormControl } from 'react-bootstrap';
|
||||
import Button from 'src/components/Button';
|
||||
import Dialog from 'react-bootstrap-dialog';
|
||||
import { AsyncSelect } from 'src/components/Select';
|
||||
@ -30,6 +30,7 @@ import {
|
||||
getCategoricalSchemeRegistry,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import Modal from 'src/common/components/Modal';
|
||||
import FormLabel from 'src/components/FormLabel';
|
||||
import { JsonEditor } from 'src/components/AsyncAceEditor';
|
||||
|
||||
@ -292,16 +293,41 @@ class PropertiesModal extends React.PureComponent {
|
||||
const saveLabel = onlyApply ? t('Apply') : t('Save');
|
||||
|
||||
return (
|
||||
<Modal show={this.props.show} onHide={this.props.onHide} bsSize="lg">
|
||||
<Modal
|
||||
show={this.props.show}
|
||||
onHide={this.props.onHide}
|
||||
title={t('Dashboard Properties')}
|
||||
footer={
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
buttonSize="sm"
|
||||
onClick={onHide}
|
||||
data-test="properties-modal-cancel-button"
|
||||
cta
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={this.submit}
|
||||
buttonSize="sm"
|
||||
buttonStyle="primary"
|
||||
className="m-r-5"
|
||||
disabled={errors.length > 0}
|
||||
cta
|
||||
>
|
||||
{saveLabel}
|
||||
</Button>
|
||||
<Dialog
|
||||
ref={ref => {
|
||||
this.dialog = ref;
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
responsive
|
||||
>
|
||||
<form onSubmit={this.submit}>
|
||||
<Modal.Header closeButton data-test="dashboard-properties-modal">
|
||||
<Modal.Title>
|
||||
<div>
|
||||
<span className="float-left">{t('Dashboard Properties')}</span>
|
||||
</div>
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<h3>{t('Basic Information')}</h3>
|
||||
@ -402,35 +428,6 @@ class PropertiesModal extends React.PureComponent {
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<span className="float-right">
|
||||
<Button
|
||||
type="button"
|
||||
buttonSize="sm"
|
||||
onClick={onHide}
|
||||
data-test="properties-modal-cancel-button"
|
||||
cta
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
buttonSize="sm"
|
||||
buttonStyle="primary"
|
||||
className="m-r-5"
|
||||
disabled={errors.length > 0}
|
||||
cta
|
||||
>
|
||||
{saveLabel}
|
||||
</Button>
|
||||
<Dialog
|
||||
ref={ref => {
|
||||
this.dialog = ref;
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</Modal.Footer>
|
||||
</form>
|
||||
</Modal>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user