diff --git a/superset-frontend/src/components/Chart/ChartContainer.jsx b/superset-frontend/src/components/Chart/ChartContainer.tsx similarity index 89% rename from superset-frontend/src/components/Chart/ChartContainer.jsx rename to superset-frontend/src/components/Chart/ChartContainer.tsx index 50c036c28db..14390e49a85 100644 --- a/superset-frontend/src/components/Chart/ChartContainer.jsx +++ b/superset-frontend/src/components/Chart/ChartContainer.tsx @@ -17,21 +17,21 @@ * under the License. */ import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; +import { bindActionCreators, Dispatch, AnyAction } from 'redux'; import * as actions from './chartAction'; import { logEvent } from '../../logger/actions'; import Chart from './Chart'; import { updateDataMask } from '../../dataMask/actions'; -function mapDispatchToProps(dispatch) { +function mapDispatchToProps(dispatch: Dispatch) { return { actions: bindActionCreators( { ...actions, updateDataMask, logEvent, - }, + } as any, dispatch, ), }; diff --git a/superset-frontend/src/dashboard/components/MissingChart.jsx b/superset-frontend/src/dashboard/components/MissingChart.tsx similarity index 86% rename from superset-frontend/src/dashboard/components/MissingChart.jsx rename to superset-frontend/src/dashboard/components/MissingChart.tsx index dc5fb352749..5332836b33e 100644 --- a/superset-frontend/src/dashboard/components/MissingChart.jsx +++ b/superset-frontend/src/dashboard/components/MissingChart.tsx @@ -16,14 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; import { t } from '@superset-ui/core'; -const propTypes = { - height: PropTypes.number.isRequired, -}; +interface MissingChartProps { + height: number; +} -export default function MissingChart({ height }) { +export default function MissingChart({ height }: MissingChartProps) { return (
@@ -37,5 +36,3 @@ export default function MissingChart({ height }) {
); } - -MissingChart.propTypes = propTypes; diff --git a/superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.jsx b/superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.tsx similarity index 81% rename from superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.jsx rename to superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.tsx index 6beb78c894c..41bbc4c77de 100644 --- a/superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.jsx +++ b/superset-frontend/src/dashboard/components/filterscope/FilterFieldItem.tsx @@ -16,16 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; import cx from 'classnames'; import { FormLabel } from '@superset-ui/core/components'; -const propTypes = { - label: PropTypes.string.isRequired, - isSelected: PropTypes.bool.isRequired, -}; +interface FilterFieldItemProps { + label: string; + isSelected: boolean; +} -export default function FilterFieldItem({ label, isSelected }) { +export default function FilterFieldItem({ + label, + isSelected, +}: FilterFieldItemProps) { return ( ); } - -FilterFieldItem.propTypes = propTypes; diff --git a/superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.jsx b/superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.tsx similarity index 54% rename from superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.jsx rename to superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.tsx index b34b1d32466..e88f25159b3 100644 --- a/superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.jsx +++ b/superset-frontend/src/dashboard/components/filterscope/FilterFieldTree.tsx @@ -16,47 +16,39 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; -import CheckboxTree from 'react-checkbox-tree'; -import { filterScopeSelectorTreeNodePropShape } from 'src/dashboard/util/propShapes'; +import CheckboxTree, { Node, OnCheckNode } from 'react-checkbox-tree'; import treeIcons from './treeIcons'; -import renderFilterFieldTreeNodes from './renderFilterFieldTreeNodes'; +import renderFilterFieldTreeNodes, { + FilterScopeTreeNode, +} from './renderFilterFieldTreeNodes'; -const propTypes = { - activeKey: PropTypes.string, - nodes: PropTypes.arrayOf(filterScopeSelectorTreeNodePropShape).isRequired, - checked: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - ).isRequired, - expanded: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - ).isRequired, - onCheck: PropTypes.func.isRequired, - onExpand: PropTypes.func.isRequired, - onClick: PropTypes.func.isRequired, -}; - -const defaultProps = { - activeKey: null, -}; +interface FilterFieldTreeProps { + activeKey?: string | null; + nodes: FilterScopeTreeNode[]; + checked: (string | number)[]; + expanded: (string | number)[]; + onCheck: (checked: string[]) => void; + onExpand: (expanded: string[]) => void; + onClick: (node: OnCheckNode) => void; +} export default function FilterFieldTree({ - activeKey, + activeKey = null, nodes = [], checked = [], expanded = [], onClick, onCheck, onExpand, -}) { +}: FilterFieldTreeProps) { return ( ); } - -FilterFieldTree.propTypes = propTypes; -FilterFieldTree.defaultProps = defaultProps; diff --git a/superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.jsx b/superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.tsx similarity index 58% rename from superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.jsx rename to superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.tsx index 436c4d7f5c7..4e901dae940 100644 --- a/superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.jsx +++ b/superset-frontend/src/dashboard/components/filterscope/FilterScopeTree.tsx @@ -16,28 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; -import CheckboxTree from 'react-checkbox-tree'; -import { filterScopeSelectorTreeNodePropShape } from 'src/dashboard/util/propShapes'; -import renderFilterScopeTreeNodes from './renderFilterScopeTreeNodes'; +import CheckboxTree, { Node } from 'react-checkbox-tree'; +import renderFilterScopeTreeNodes, { + FilterScopeTreeNode, +} from './renderFilterScopeTreeNodes'; import treeIcons from './treeIcons'; -const propTypes = { - nodes: PropTypes.arrayOf(filterScopeSelectorTreeNodePropShape).isRequired, - checked: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - ).isRequired, - expanded: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - ).isRequired, - onCheck: PropTypes.func.isRequired, - onExpand: PropTypes.func.isRequired, - selectedChartId: PropTypes.number, -}; - -const defaultProps = { - selectedChartId: null, -}; +interface FilterScopeTreeProps { + nodes: FilterScopeTreeNode[]; + checked: (string | number)[]; + expanded: (string | number)[]; + onCheck: (checked: string[]) => void; + onExpand: (expanded: string[]) => void; + selectedChartId?: number | null; +} const NOOP = () => {}; @@ -47,16 +39,16 @@ export default function FilterScopeTree({ expanded = [], onCheck, onExpand, - selectedChartId, -}) { + selectedChartId = null, +}: FilterScopeTreeProps) { return ( ); } - -FilterScopeTree.propTypes = propTypes; -FilterScopeTree.defaultProps = defaultProps; diff --git a/superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.jsx b/superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.tsx similarity index 63% rename from superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.jsx rename to superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.tsx index aca870f4a20..7d1a2dabfd1 100644 --- a/superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.jsx +++ b/superset-frontend/src/dashboard/components/filterscope/renderFilterFieldTreeNodes.tsx @@ -16,23 +16,42 @@ * specific language governing permissions and limitations * under the License. */ +import { ReactNode } from 'react'; import FilterFieldItem from './FilterFieldItem'; -export default function renderFilterFieldTreeNodes({ nodes, activeKey }) { - if (!nodes) { +export interface FilterScopeTreeNode { + value: string | number; + label: string | ReactNode; + type?: string; + children?: FilterScopeTreeNode[]; +} + +interface RenderFilterFieldTreeNodesParams { + nodes: FilterScopeTreeNode[] | null; + activeKey?: string | null; +} + +export default function renderFilterFieldTreeNodes({ + nodes, + activeKey, +}: RenderFilterFieldTreeNodesParams): FilterScopeTreeNode[] { + if (!nodes || nodes.length === 0) { return []; } const root = nodes[0]; - const allFilterNodes = root.children; + const allFilterNodes = root.children || []; const children = allFilterNodes.map(node => ({ ...node, - children: node.children.map(child => { + children: (node.children || []).map(child => { const { label, value } = child; return { ...child, label: ( - + ), }; }), diff --git a/superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.jsx b/superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.tsx similarity index 71% rename from superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.jsx rename to superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.tsx index da7ce57f2fb..3867a69aad9 100644 --- a/superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.jsx +++ b/superset-frontend/src/dashboard/components/filterscope/renderFilterScopeTreeNodes.tsx @@ -16,11 +16,29 @@ * specific language governing permissions and limitations * under the License. */ +import { ReactNode } from 'react'; import cx from 'classnames'; import { styled } from '@apache-superset/core/ui'; import { Icons } from '@superset-ui/core/components/Icons'; import { CHART_TYPE } from 'src/dashboard/util/componentTypes'; +export interface FilterScopeTreeNode { + value: string | number; + label: string | ReactNode; + type?: string; + children?: FilterScopeTreeNode[]; +} + +interface TraverseParams { + currentNode: FilterScopeTreeNode; + selectedChartId?: number | null; +} + +interface RenderFilterScopeTreeNodesParams { + nodes: FilterScopeTreeNode[] | null; + selectedChartId?: number | null; +} + const ChartIcon = styled(Icons.BarChartOutlined)` ${({ theme }) => ` position: relative; @@ -30,11 +48,10 @@ const ChartIcon = styled(Icons.BarChartOutlined)` `} `; -function traverse({ currentNode = {}, selectedChartId }) { - if (!currentNode) { - return null; - } - +function traverse({ + currentNode, + selectedChartId, +}: TraverseParams): FilterScopeTreeNode { const { label, value, type, children } = currentNode; if (children && children.length) { const updatedChildren = children.map(child => @@ -44,7 +61,7 @@ function traverse({ currentNode = {}, selectedChartId }) { ...currentNode, label: ( @@ -59,7 +76,7 @@ function traverse({ currentNode = {}, selectedChartId }) { ...currentNode, label: ( @@ -69,7 +86,10 @@ function traverse({ currentNode = {}, selectedChartId }) { }; } -export default function renderFilterScopeTreeNodes({ nodes, selectedChartId }) { +export default function renderFilterScopeTreeNodes({ + nodes, + selectedChartId, +}: RenderFilterScopeTreeNodesParams): FilterScopeTreeNode[] { if (!nodes) { return []; } diff --git a/superset-frontend/src/dashboard/components/filterscope/treeIcons.jsx b/superset-frontend/src/dashboard/components/filterscope/treeIcons.tsx similarity index 100% rename from superset-frontend/src/dashboard/components/filterscope/treeIcons.jsx rename to superset-frontend/src/dashboard/components/filterscope/treeIcons.tsx diff --git a/superset-frontend/src/dashboard/containers/DashboardGrid.jsx b/superset-frontend/src/dashboard/containers/DashboardGrid.tsx similarity index 86% rename from superset-frontend/src/dashboard/containers/DashboardGrid.jsx rename to superset-frontend/src/dashboard/containers/DashboardGrid.tsx index ca214fe8787..977e17716f7 100644 --- a/superset-frontend/src/dashboard/containers/DashboardGrid.jsx +++ b/superset-frontend/src/dashboard/containers/DashboardGrid.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { bindActionCreators } from 'redux'; +import { bindActionCreators, Dispatch } from 'redux'; import { connect } from 'react-redux'; import DashboardGrid from '../components/DashboardGrid'; @@ -25,8 +25,9 @@ import { resizeComponent, } from '../actions/dashboardLayout'; import { setDirectPathToChild, setEditMode } from '../actions/dashboardState'; +import { RootState } from 'src/dashboard/types'; -function mapStateToProps({ dashboardState, dashboardInfo }) { +function mapStateToProps({ dashboardState, dashboardInfo }: RootState) { return { editMode: dashboardState.editMode, canEdit: dashboardInfo.dash_edit_perm, @@ -34,7 +35,7 @@ function mapStateToProps({ dashboardState, dashboardInfo }) { }; } -function mapDispatchToProps(dispatch) { +function mapDispatchToProps(dispatch: Dispatch) { return bindActionCreators( { handleComponentDrop, diff --git a/superset-frontend/src/dashboard/containers/FilterScope.jsx b/superset-frontend/src/dashboard/containers/FilterScope.tsx similarity index 85% rename from superset-frontend/src/dashboard/containers/FilterScope.jsx rename to superset-frontend/src/dashboard/containers/FilterScope.tsx index d816df9fff7..e8404db2236 100644 --- a/superset-frontend/src/dashboard/containers/FilterScope.jsx +++ b/superset-frontend/src/dashboard/containers/FilterScope.tsx @@ -17,20 +17,21 @@ * under the License. */ import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; +import { bindActionCreators, Dispatch } from 'redux'; import { updateDashboardFiltersScope } from '../actions/dashboardFilters'; import { setUnsavedChanges } from '../actions/dashboardState'; import FilterScopeSelector from '../components/filterscope/FilterScopeSelector'; +import { RootState } from 'src/dashboard/types'; -function mapStateToProps({ dashboardLayout, dashboardFilters }) { +function mapStateToProps({ dashboardLayout, dashboardFilters }: RootState) { return { dashboardFilters, layout: dashboardLayout.present, }; } -function mapDispatchToProps(dispatch) { +function mapDispatchToProps(dispatch: Dispatch) { return bindActionCreators( { updateDashboardFiltersScope, diff --git a/superset-frontend/src/dashboard/containers/SliceAdder.jsx b/superset-frontend/src/dashboard/containers/SliceAdder.tsx similarity index 82% rename from superset-frontend/src/dashboard/containers/SliceAdder.jsx rename to superset-frontend/src/dashboard/containers/SliceAdder.tsx index 992098a0da2..f8640f4ccbf 100644 --- a/superset-frontend/src/dashboard/containers/SliceAdder.jsx +++ b/superset-frontend/src/dashboard/containers/SliceAdder.tsx @@ -16,14 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -import { bindActionCreators } from 'redux'; +import { bindActionCreators, Dispatch, AnyAction } from 'redux'; import { connect } from 'react-redux'; import { fetchSlices, updateSlices } from '../actions/sliceEntities'; import SliceAdder from '../components/SliceAdder'; +import { RootState } from 'src/dashboard/types'; + +interface OwnProps { + height?: number; +} function mapStateToProps( - { sliceEntities, dashboardInfo, dashboardState }, - ownProps, + { sliceEntities, dashboardInfo, dashboardState }: RootState, + ownProps: OwnProps, ) { return { height: ownProps.height, @@ -38,14 +43,14 @@ function mapStateToProps( }; } -function mapDispatchToProps(dispatch) { +function mapDispatchToProps(dispatch: Dispatch) { return bindActionCreators( { fetchSlices, updateSlices, - }, + } as any, dispatch, ); } -export default connect(mapStateToProps, mapDispatchToProps)(SliceAdder); +export default connect(mapStateToProps, mapDispatchToProps)(SliceAdder as any); diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.tsx similarity index 74% rename from superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.jsx rename to superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.tsx index b3a601a110b..31a9445aa99 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AggregateOption.tsx @@ -16,22 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; import { ColumnTypeLabel } from '@superset-ui/chart-controls'; +import { AggregateOption as AggregateOptionType } from './types'; -import aggregateOptionType from './aggregateOptionType'; +interface AggregateOptionProps { + aggregate: AggregateOptionType; + showType?: boolean; +} -const propTypes = { - aggregate: aggregateOptionType, - showType: PropTypes.bool, -}; - -export default function AggregateOption({ aggregate, showType }) { +export default function AggregateOption({ + aggregate, + showType, +}: AggregateOptionProps) { return (
- {showType && } + {showType && } {aggregate.aggregate_name}
); } -AggregateOption.propTypes = propTypes; diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.tsx similarity index 66% rename from superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx rename to superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.tsx index c0f27435b9a..c3e716bff45 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.tsx @@ -16,35 +16,40 @@ * specific language governing permissions and limitations * under the License. */ -import PropTypes from 'prop-types'; import { StyledColumnOption, StyledMetricOption, } from 'src/explore/components/optionRenderers'; import withToasts from 'src/components/MessageToasts/withToasts'; import AggregateOption from './AggregateOption'; -import columnType from './columnType'; -import aggregateOptionType from './aggregateOptionType'; -import savedMetricType from './savedMetricType'; -const propTypes = { - option: PropTypes.oneOfType([ - columnType, - savedMetricType, - aggregateOptionType, - ]).isRequired, - addWarningToast: PropTypes.func.isRequired, -}; +interface MetricDefinitionOptionProps { + option: { + metric_name?: string; + column_name?: string; + aggregate_name?: string; + [key: string]: unknown; + }; + addWarningToast: (message: string) => void; +} -function MetricDefinitionOption({ option, addWarningToast }) { +function MetricDefinitionOption({ + option, + addWarningToast, +}: MetricDefinitionOptionProps) { if (option.metric_name) { - return ; + return ; } if (option.column_name) { - return ; + return ; } if (option.aggregate_name) { - return ; + return ( + + ); } addWarningToast( 'You must supply either a saved metric, column or aggregate to MetricDefinitionOption', @@ -52,6 +57,4 @@ function MetricDefinitionOption({ option, addWarningToast }) { return null; } -MetricDefinitionOption.propTypes = propTypes; - export default withToasts(MetricDefinitionOption);