fix: save query modal/button styling + convert to ant-d modal (#11164)

This commit is contained in:
Moriah Kreeger
2020-10-06 16:55:17 -07:00
committed by GitHub
parent fb8320f7fe
commit 21c8d672a8
5 changed files with 230 additions and 209 deletions

View File

@@ -1,198 +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 PropTypes from 'prop-types';
import { FormControl, FormGroup, Row, Col } from 'react-bootstrap';
import { t } from '@superset-ui/core';
import Button from 'src/components/Button';
import FormLabel from 'src/components/FormLabel';
import ModalTrigger from 'src/components/ModalTrigger';
const propTypes = {
query: PropTypes.object,
defaultLabel: PropTypes.string,
animation: PropTypes.bool,
onSave: PropTypes.func,
onUpdate: PropTypes.func,
saveQueryWarning: PropTypes.string,
};
const defaultProps = {
defaultLabel: t('Undefined'),
animation: true,
onSave: () => {},
saveQueryWarning: null,
};
class SaveQuery extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
description: '',
label: props.defaultLabel,
showSave: false,
};
this.toggleSave = this.toggleSave.bind(this);
this.onSave = this.onSave.bind(this);
this.onUpdate = this.onUpdate.bind(this);
this.onCancel = this.onCancel.bind(this);
this.onLabelChange = this.onLabelChange.bind(this);
this.onDescriptionChange = this.onDescriptionChange.bind(this);
}
onSave() {
this.props.onSave(this.queryPayload());
this.close();
}
onUpdate() {
this.props.onUpdate(this.queryPayload());
this.close();
}
onCancel() {
this.close();
}
onLabelChange(e) {
this.setState({ label: e.target.value });
}
onDescriptionChange(e) {
this.setState({ description: e.target.value });
}
queryPayload() {
return {
...this.props.query,
title: this.state.label,
description: this.state.description,
};
}
close() {
if (this.saveModal) this.saveModal.close();
}
toggleSave() {
this.setState(prevState => ({ showSave: !prevState.showSave }));
}
renderModalBody() {
const isSaved = !!this.props.query.remoteId;
return (
<FormGroup bsSize="small">
<Row>
<Col md={12}>
<small>
<FormLabel className="control-label" htmlFor="embed-height">
{t('Label')}
</FormLabel>
</small>
<FormControl
type="text"
placeholder={t('Label for your query')}
value={this.state.label}
onChange={this.onLabelChange}
/>
</Col>
</Row>
<br />
<Row>
<Col md={12}>
<small>
<FormLabel className="control-label" htmlFor="embed-height">
{t('Description')}
</FormLabel>
</small>
<FormControl
componentClass="textarea"
placeholder={t('Write a description for your query')}
value={this.state.description}
onChange={this.onDescriptionChange}
/>
</Col>
</Row>
<br />
{this.props.saveQueryWarning && (
<div>
<Row>
<Col md={12}>
<small>{this.props.saveQueryWarning}</small>
</Col>
</Row>
<br />
</div>
)}
<Row>
<Col md={12}>
{isSaved && (
<Button
buttonStyle="primary"
onClick={this.onUpdate}
className="m-r-3"
>
{t('Update')}
</Button>
)}
<Button
buttonStyle={isSaved ? undefined : 'primary'}
onClick={this.onSave}
className="m-r-3"
>
{isSaved ? t('Save New') : t('Save')}
</Button>
<Button onClick={this.onCancel} className="cancelQuery">
{t('Cancel')}
</Button>
</Col>
</Row>
</FormGroup>
);
}
render() {
return (
<span className="SaveQuery">
<ModalTrigger
ref={ref => {
this.saveModal = ref;
}}
modalTitle={t('Save Query')}
modalBody={this.renderModalBody()}
backdrop="static"
triggerNode={
<Button
buttonSize="small"
className="toggleSave"
onClick={this.toggleSave}
>
<i className="fa fa-save" /> {t('Save')}
</Button>
}
bsSize="small"
/>
</span>
);
}
}
SaveQuery.propTypes = propTypes;
SaveQuery.defaultProps = defaultProps;
export default SaveQuery;

View File

@@ -0,0 +1,215 @@
/**
* 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, { useState } from 'react';
import { FormControl, FormGroup, Row, Col } from 'react-bootstrap';
import { t, styled } from '@superset-ui/core';
import Button from 'src/components/Button';
import FormLabel from 'src/components/FormLabel';
import Modal from 'src/common/components/Modal';
interface SaveQueryProps {
query: any;
defaultLabel: string;
onSave: (arg0: QueryPayload) => void;
onUpdate: (arg0: QueryPayload) => void;
saveQueryWarning: string | null;
}
type QueryPayload = {
autorun: boolean;
dbId: number;
description?: string;
id?: string;
latestQueryId: string;
queryLimit: number;
remoteId: number;
schema: string;
schemaOptions: Array<{
label: string;
title: string;
value: string;
}>;
selectedText: string | null;
sql: string;
tableOptions: Array<{
label: string;
schema: string;
title: string;
type: string;
value: string;
}>;
title: string;
};
const StyledRow = styled(Row)`
div {
display: flex;
justify-content: flex-start;
}
button.cta {
margin: 0 7px;
min-width: 105px;
font-size: 12px;
&:first-of-type {
margin-left: 0;
}
}
`;
export default function SaveQuery({
query,
defaultLabel = t('Undefined'),
onSave = () => {},
onUpdate,
saveQueryWarning = null,
}: SaveQueryProps) {
const [description, setDescription] = useState<string>(
query.description || '',
);
const [label, setLabel] = useState<string>(defaultLabel);
const [showSave, setShowSave] = useState<boolean>(false);
const isSaved = !!query.remoteId;
const queryPayload = () => {
return {
...query,
title: label,
description,
};
};
const close = () => {
setShowSave(false);
};
const onSaveWrapper = () => {
onSave(queryPayload());
close();
};
const onUpdateWrapper = () => {
onUpdate(queryPayload());
close();
};
const onLabelChange = (e: React.FormEvent<FormControl>) => {
setLabel((e.target as HTMLInputElement).value);
};
const onDescriptionChange = (e: React.FormEvent<FormControl>) => {
setDescription((e.target as HTMLInputElement).value);
};
const toggleSave = () => {
setShowSave(!showSave);
};
const renderModalBody = () => {
return (
<FormGroup bsSize="small">
<Row>
<Col md={12}>
<small>
<FormLabel htmlFor="embed-height">{t('Label')}</FormLabel>
</small>
<FormControl
type="text"
placeholder={t('Label for your query')}
value={label}
onChange={onLabelChange}
/>
</Col>
</Row>
<br />
<Row>
<Col md={12}>
<small>
<FormLabel htmlFor="embed-height">{t('Description')}</FormLabel>
</small>
<FormControl
componentClass="textarea"
placeholder={t('Write a description for your query')}
value={description}
onChange={onDescriptionChange}
/>
</Col>
</Row>
<br />
{saveQueryWarning && (
<div>
<Row>
<Col md={12}>
<small>{saveQueryWarning}</small>
</Col>
</Row>
<br />
</div>
)}
<StyledRow>
<Col md={12}>
{isSaved && (
<Button
buttonStyle="primary"
onClick={onUpdateWrapper}
className="m-r-3"
cta
>
{t('Update')}
</Button>
)}
<Button
buttonStyle={isSaved ? undefined : 'primary'}
onClick={onSaveWrapper}
className="m-r-3"
cta
>
{isSaved ? t('Save New') : t('Save')}
</Button>
<Button onClick={close} className="cancelQuery" cta>
{t('Cancel')}
</Button>
</Col>
</StyledRow>
</FormGroup>
);
};
return (
<span className="SaveQuery">
<Button buttonSize="small" className="toggleSave" onClick={toggleSave}>
<i className="fa fa-save" /> {t('Save')}
</Button>
<Modal
className="save-query-modal"
onHandledPrimaryAction={onSaveWrapper}
onHide={close}
primaryButtonName={isSaved ? t('Save') : t('Add')}
width="390px"
show={showSave}
title={<h4>{t('Save Query')}</h4>}
hideFooter
>
{renderModalBody()}
</Modal>
</span>
);
}

View File

@@ -529,9 +529,7 @@ class SqlEditor extends React.PureComponent {
<span>
<SaveQuery
query={qe}
defaultLabel={
qe.description == null ? qe.title : qe.description
}
defaultLabel={qe.title || qe.description}
onSave={this.props.actions.saveQuery}
onUpdate={this.props.actions.updateSavedQuery}
saveQueryWarning={this.props.saveQueryWarning}