From eecdd20301698b20b63d9d1dc887a2b230ae34a6 Mon Sep 17 00:00:00 2001 From: Victor Malai Date: Mon, 21 Dec 2020 18:56:36 +0200 Subject: [PATCH] refactor: Explore SaveModal to typescript (#11997) * Explore SaveModal to typescript * Fix test * Fix * Fix lint * update SaveModal without any type * Update * Fix lint * Fix lint * Fix test * Fix * Fix * Fix lint * Refactor * Fix --- .../src/components/Button/index.tsx | 1 + .../src/explore/actions/saveModalActions.js | 5 +- .../{SaveModal.jsx => SaveModal.tsx} | 88 +++++++++++-------- 3 files changed, 57 insertions(+), 37 deletions(-) rename superset-frontend/src/explore/components/{SaveModal.jsx => SaveModal.tsx} (81%) diff --git a/superset-frontend/src/components/Button/index.tsx b/superset-frontend/src/components/Button/index.tsx index a7fc0ba755..54ebe78245 100644 --- a/superset-frontend/src/components/Button/index.tsx +++ b/superset-frontend/src/components/Button/index.tsx @@ -34,6 +34,7 @@ export interface DropdownItemProps { } export interface ButtonProps { + id?: string; className?: string; tooltip?: string; placement?: diff --git a/superset-frontend/src/explore/actions/saveModalActions.js b/superset-frontend/src/explore/actions/saveModalActions.js index 2137bc1eda..0a0bd9a980 100644 --- a/superset-frontend/src/explore/actions/saveModalActions.js +++ b/superset-frontend/src/explore/actions/saveModalActions.js @@ -71,7 +71,10 @@ export function saveSlice(formData, requestParams) { }); return SupersetClient.post({ url, postPayload: { form_data: formData } }) - .then(({ json }) => dispatch(saveSliceSuccess(json))) + .then(response => { + dispatch(saveSliceSuccess(response.json)); + return response; + }) .catch(() => dispatch(saveSliceFailed())); }; } diff --git a/superset-frontend/src/explore/components/SaveModal.jsx b/superset-frontend/src/explore/components/SaveModal.tsx similarity index 81% rename from superset-frontend/src/explore/components/SaveModal.jsx rename to superset-frontend/src/explore/components/SaveModal.tsx index ddf8c3e60a..7e975d5b15 100644 --- a/superset-frontend/src/explore/components/SaveModal.jsx +++ b/superset-frontend/src/explore/components/SaveModal.tsx @@ -18,35 +18,45 @@ */ /* eslint camelcase: 0 */ import React from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; import { Alert, FormControl, FormGroup, Radio } from 'react-bootstrap'; -import { t } from '@superset-ui/core'; +import { JsonObject, t } from '@superset-ui/core'; import ReactMarkdown from 'react-markdown'; import Modal from 'src/common/components/Modal'; import Button from 'src/components/Button'; import FormLabel from 'src/components/FormLabel'; import { CreatableSelect } from 'src/components/Select/SupersetStyledSelect'; - -const propTypes = { - can_overwrite: PropTypes.bool, - onHide: PropTypes.func.isRequired, - actions: PropTypes.object.isRequired, - form_data: PropTypes.object, - userId: PropTypes.string.isRequired, - dashboards: PropTypes.array.isRequired, - alert: PropTypes.string, - slice: PropTypes.object, - datasource: PropTypes.object, - dashboardId: PropTypes.number, -}; +import { connect } from 'react-redux'; // Session storage key for recent dashboard const SK_DASHBOARD_ID = 'save_chart_recent_dashboard'; const SELECT_PLACEHOLDER = t('**Select** a dashboard OR **create** a new one'); -class SaveModal extends React.Component { - constructor(props) { +type SaveModalProps = { + can_overwrite?: boolean; + onHide: () => void; + actions: Record; + form_data?: Record; + userId: string; + dashboards: Array; + alert?: string; + sliceName?: string; + slice?: Record; + datasource?: Record; + dashboardId: '' | number | null; +}; + +type ActionType = 'overwrite' | 'saveas'; + +type SaveModalState = { + saveToDashboardId: number | string | null; + newSliceName?: string; + newDashboardName?: string; + alert: string | null; + action: ActionType; +}; + +class SaveModal extends React.Component { + constructor(props: SaveModalProps) { super(props); this.state = { saveToDashboardId: null, @@ -56,6 +66,8 @@ class SaveModal extends React.Component { }; this.onDashboardSelectChange = this.onDashboardSelectChange.bind(this); this.onSliceNameChange = this.onSliceNameChange.bind(this); + this.changeAction = this.changeAction.bind(this); + this.saveOrOverwrite = this.saveOrOverwrite.bind(this); } componentDidMount() { @@ -63,8 +75,8 @@ class SaveModal extends React.Component { const dashboardIds = this.props.dashboards.map( dashboard => dashboard.value, ); - let recentDashboard = sessionStorage.getItem(SK_DASHBOARD_ID); - recentDashboard = recentDashboard && parseInt(recentDashboard, 10); + const lastDashboard = sessionStorage.getItem(SK_DASHBOARD_ID); + let recentDashboard = lastDashboard && parseInt(lastDashboard, 10); if (!recentDashboard && this.props.dashboardId) { recentDashboard = this.props.dashboardId; @@ -81,25 +93,27 @@ class SaveModal extends React.Component { }); } - onSliceNameChange(event) { + onSliceNameChange( + event: React.FormEvent & { target: HTMLInputElement }, + ) { this.setState({ newSliceName: event.target.value }); } - onDashboardSelectChange(event) { + onDashboardSelectChange(event: Record) { const newDashboardName = event ? event.label : null; const saveToDashboardId = event && typeof event.value === 'number' ? event.value : null; this.setState({ saveToDashboardId, newDashboardName }); } - changeAction(action) { + changeAction(action: ActionType) { this.setState({ action }); } - saveOrOverwrite(gotodash) { + saveOrOverwrite(gotodash: boolean) { this.setState({ alert: null }); this.props.actions.removeSaveModalAlert(); - const sliceParams = {}; + const sliceParams: Record = {}; if (this.props.slice && this.props.slice.slice_id) { sliceParams.slice_id = this.props.slice.slice_id; @@ -117,7 +131,7 @@ class SaveModal extends React.Component { this.props.actions .saveSlice(this.props.form_data, sliceParams) - .then(({ data }) => { + .then(({ data }: JsonObject) => { if (data.dashboard_id === null) { sessionStorage.removeItem(SK_DASHBOARD_ID); } else { @@ -155,7 +169,7 @@ class SaveModal extends React.Component { !this.state.newSliceName || (!this.state.saveToDashboardId && !this.state.newDashboardName) } - onClick={this.saveOrOverwrite.bind(this, true)} + onClick={() => this.saveOrOverwrite(true)} > {t('Save & go to dashboard')} @@ -163,7 +177,7 @@ class SaveModal extends React.Component { id="btn_modal_save" buttonSize="sm" buttonStyle="primary" - onClick={this.saveOrOverwrite.bind(this, false)} + onClick={() => this.saveOrOverwrite(false)} disabled={!this.state.newSliceName} data-test="btn-modal-save" > @@ -194,7 +208,7 @@ class SaveModal extends React.Component { inline disabled={!(this.props.can_overwrite && this.props.slice)} checked={this.state.action === 'overwrite'} - onChange={this.changeAction.bind(this, 'overwrite')} + onChange={() => this.changeAction('overwrite')} data-test="save-overwrite-radio" > {t('Save (Overwrite)')} @@ -204,7 +218,7 @@ class SaveModal extends React.Component { data-test="saveas-radio" inline checked={this.state.action === 'saveas'} - onChange={this.changeAction.bind(this, 'saveas')} + onChange={() => this.changeAction('saveas')} > {' '} {t('Save as ...')}   @@ -233,9 +247,10 @@ class SaveModal extends React.Component { creatable onChange={this.onDashboardSelectChange} autoSize={false} - value={ - this.state.saveToDashboardId || this.state.newDashboardName - } + value={{ + value: + this.state.saveToDashboardId || this.state.newDashboardName, + }} placeholder={ // Using markdown to allow for good i18n ): Partial { return { datasource: explore.datasource, slice: explore.slice,