diff --git a/superset-frontend/src/components/Checkbox/Checkbox.test.tsx b/superset-frontend/src/components/Checkbox/Checkbox.test.tsx index 186a5bdf05..7877b7e66f 100644 --- a/superset-frontend/src/components/Checkbox/Checkbox.test.tsx +++ b/superset-frontend/src/components/Checkbox/Checkbox.test.tsx @@ -67,9 +67,9 @@ describe('Checkbox', () => { it('renders custom Checkbox styles without melting', () => { wrapper = mount( - true} checked={false} style={{ foo: 'foo' }} />, + true} checked={false} style={{ opacity: 1 }} />, ); expect(wrapper.find('Checkbox')).toExist(); - expect(wrapper.find('Checkbox')).toHaveStyle({ foo: 'foo' }); + expect(wrapper.find('Checkbox')).toHaveStyle({ opacity: 1 }); }); }); diff --git a/superset-frontend/src/components/Checkbox/index.tsx b/superset-frontend/src/components/Checkbox/index.tsx index 621ce1755c..3ff55ad7a3 100644 --- a/superset-frontend/src/components/Checkbox/index.tsx +++ b/superset-frontend/src/components/Checkbox/index.tsx @@ -25,8 +25,8 @@ import { interface CheckboxProps { checked: boolean; - onChange: (val?: boolean) => {}; - style: object; + onChange: (val?: boolean) => void; + style?: React.CSSProperties; } const Styles = styled.span` diff --git a/superset-frontend/src/dashboard/components/SaveModal.jsx b/superset-frontend/src/dashboard/components/SaveModal.tsx similarity index 72% rename from superset-frontend/src/dashboard/components/SaveModal.jsx rename to superset-frontend/src/dashboard/components/SaveModal.tsx index 46c4c55e2c..c8f327b3e1 100644 --- a/superset-frontend/src/dashboard/components/SaveModal.jsx +++ b/superset-frontend/src/dashboard/components/SaveModal.tsx @@ -18,42 +18,64 @@ */ /* eslint-env browser */ import React from 'react'; -import PropTypes from 'prop-types'; import { FormControl, FormGroup, Radio } from 'react-bootstrap'; import Button from 'src/components/Button'; -import { t, CategoricalColorNamespace } from '@superset-ui/core'; +import { t, CategoricalColorNamespace, JsonResponse } from '@superset-ui/core'; -import ModalTrigger from '../../components/ModalTrigger'; -import Checkbox from '../../components/Checkbox'; -import { SAVE_TYPE_OVERWRITE, SAVE_TYPE_NEWDASHBOARD } from '../util/constants'; +import ModalTrigger from 'src/components/ModalTrigger'; +import Checkbox from 'src/components/Checkbox'; +import { + SAVE_TYPE_OVERWRITE, + SAVE_TYPE_NEWDASHBOARD, +} from 'src/dashboard/util/constants'; -const propTypes = { - addSuccessToast: PropTypes.func.isRequired, - addDangerToast: PropTypes.func.isRequired, - dashboardId: PropTypes.number.isRequired, - dashboardTitle: PropTypes.string.isRequired, - dashboardInfo: PropTypes.object.isRequired, - expandedSlices: PropTypes.object.isRequired, - layout: PropTypes.object.isRequired, - saveType: PropTypes.oneOf([SAVE_TYPE_OVERWRITE, SAVE_TYPE_NEWDASHBOARD]), - triggerNode: PropTypes.node.isRequired, - customCss: PropTypes.string.isRequired, - colorNamespace: PropTypes.string, - colorScheme: PropTypes.string, - onSave: PropTypes.func.isRequired, - canOverwrite: PropTypes.bool.isRequired, - refreshFrequency: PropTypes.number.isRequired, - lastModifiedTime: PropTypes.number.isRequired, +type SaveType = typeof SAVE_TYPE_OVERWRITE | typeof SAVE_TYPE_NEWDASHBOARD; + +type SaveModalProps = { + addSuccessToast: (arg: string) => void; + addDangerToast: (arg: string) => void; + dashboardId: number; + dashboardTitle: string; + dashboardInfo: Record; + expandedSlices: Record; + layout: Record; + saveType: SaveType; + triggerNode: JSX.Element; + customCss: string; + colorNamespace?: string; + colorScheme?: string; + onSave: (data: any, id: number | string, saveType: SaveType) => void; + canOverwrite: boolean; + shouldPersistRefreshFrequency: boolean; + refreshFrequency: number; + lastModifiedTime: number; +}; + +type SaveModalState = { + saveType: SaveType; + newDashName: string; + duplicateSlices: boolean; }; const defaultProps = { saveType: SAVE_TYPE_OVERWRITE, colorNamespace: undefined, colorScheme: undefined, + shouldPersistRefreshFrequency: false, }; -class SaveModal extends React.PureComponent { - constructor(props) { +class SaveModal extends React.PureComponent { + static defaultProps = defaultProps; + + modal: ModalTrigger | null; + + onSave: ( + data: Record, + dashboardId: number | string, + saveType: SaveType, + ) => Promise; + + constructor(props: SaveModalProps) { super(props); this.state = { saveType: props.saveType, @@ -69,25 +91,25 @@ class SaveModal extends React.PureComponent { this.onSave = this.props.onSave.bind(this); } - setModalRef(ref) { + setModalRef(ref: ModalTrigger | null) { this.modal = ref; } - toggleDuplicateSlices() { + toggleDuplicateSlices(): void { this.setState(prevState => ({ duplicateSlices: !prevState.duplicateSlices, })); } - handleSaveTypeChange(event) { + handleSaveTypeChange(event: React.FormEvent) { this.setState({ - saveType: event.target.value, + saveType: (event.target as HTMLInputElement).value as SaveType, }); } - handleNameChange(event) { + handleNameChange(event: React.FormEvent) { this.setState({ - newDashName: event.target.value, + newDashName: (event.target as HTMLInputElement).value, saveType: SAVE_TYPE_NEWDASHBOARD, }); } @@ -137,17 +159,17 @@ class SaveModal extends React.PureComponent { t('You must pick a name for the new dashboard'), ); } else { - this.onSave(data, dashboardId, saveType).then(resp => { + this.onSave(data, dashboardId, saveType).then((resp: JsonResponse) => { if ( saveType === SAVE_TYPE_NEWDASHBOARD && resp && resp.json && resp.json.id ) { - window.location = `/superset/dashboard/${resp.json.id}/`; + window.location.href = `/superset/dashboard/${resp.json.id}/`; } }); - this.modal.close(); + this.modal?.close(); } } @@ -185,7 +207,7 @@ class SaveModal extends React.PureComponent {
this.toggleDuplicateSlices()} /> {t('also copy (duplicate) charts')}
@@ -207,7 +229,4 @@ class SaveModal extends React.PureComponent { } } -SaveModal.propTypes = propTypes; -SaveModal.defaultProps = defaultProps; - export default SaveModal;