From 75ff03178937294445524d86bcf1328c2d4dc2c8 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 23 Jul 2021 10:33:26 +0100 Subject: [PATCH] Chore: Fix TypeScript strict errors with components using connect (#37109) * Chore: Fix TypeScript strict errors with components using connect * Chore: More TypeScript fixes * Chore: Update strict check values * Still need to export these types... * Declare connector at the top of the file * Careful with find and replace... --- .../dashboard/components/DashNav/DashNav.tsx | 24 ++++---- .../containers/DashboardPage.test.tsx | 1 + .../dashboard/containers/DashboardPage.tsx | 58 +++++++++---------- .../dashboard/containers/SoloPanelPage.tsx | 30 +++++----- .../datasources/DataSourcesListPage.tsx | 51 +++++++--------- .../datasources/NewDataSourcePage.tsx | 49 +++++++--------- .../explore/RichHistory/RichHistory.tsx | 14 +++-- .../explore/RichHistory/RichHistoryCard.tsx | 45 +++++++------- .../RichHistory/RichHistoryContainer.tsx | 55 +++++++++--------- .../RichHistory/RichHistorySettings.tsx | 4 +- .../components/NewDashboardsFolder.tsx | 31 ++++------ public/app/features/teams/TeamMemberRow.tsx | 25 ++++---- public/app/features/teams/TeamMembers.tsx | 43 +++++++------- public/app/features/teams/TeamSettings.tsx | 18 +++--- .../elasticsearch/components/MetricPicker.tsx | 2 +- .../MetricEditor.test.tsx | 2 +- .../loki/components/LokiOptionFields.tsx | 3 +- .../dims/editors/ScaleDimensionEditor.tsx | 36 +++++++----- .../timeseries/plugins/ContextMenuPlugin.tsx | 2 +- scripts/ci-check-strict.sh | 2 +- 20 files changed, 235 insertions(+), 260 deletions(-) diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index f4e1d48c0d3..c34b28478c8 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -1,6 +1,6 @@ // Libaries import React, { PureComponent, FC, ReactNode } from 'react'; -import { connect, MapDispatchToProps } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; // Utils & Services import { playlistSrv } from 'app/features/playlist/PlaylistSrv'; // Components @@ -12,13 +12,19 @@ import { locationUtil, textUtil } from '@grafana/data'; import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; // Types import { DashboardModel } from '../../state'; -import { KioskMode, StoreState } from 'app/types'; +import { KioskMode } from 'app/types'; import { ShareModal } from 'app/features/dashboard/components/ShareModal'; import { SaveDashboardModalProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardModalProxy'; import { locationService } from '@grafana/runtime'; import { toggleKioskMode } from 'app/core/navigation/kiosk'; import { getDashboardSrv } from '../../services/DashboardSrv'; +const mapDispatchToProps = { + updateTimeZoneForSession, +}; + +const connector = connect(null, mapDispatchToProps); + export interface OwnProps { dashboard: DashboardModel; isFullscreen: boolean; @@ -29,10 +35,6 @@ export interface OwnProps { onAddPanel: () => void; } -interface DispatchProps { - updateTimeZoneForSession: typeof updateTimeZoneForSession; -} - interface DashNavButtonModel { show: (props: Props) => boolean; component: FC>; @@ -50,7 +52,7 @@ export function addCustomRightAction(content: DashNavButtonModel) { customRightActions.push(content); } -type Props = OwnProps & DispatchProps; +type Props = OwnProps & ConnectedProps; class DashNav extends PureComponent { constructor(props: Props) { @@ -263,10 +265,4 @@ class DashNav extends PureComponent { } } -const mapStateToProps = (state: StoreState) => ({}); - -const mapDispatchToProps: MapDispatchToProps = { - updateTimeZoneForSession, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(DashNav); +export default connector(DashNav); diff --git a/public/app/features/dashboard/containers/DashboardPage.test.tsx b/public/app/features/dashboard/containers/DashboardPage.test.tsx index 4be727e8075..961490977ff 100644 --- a/public/app/features/dashboard/containers/DashboardPage.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.test.tsx @@ -78,6 +78,7 @@ function dashboardPageScenario(description: string, scenarioFn: (ctx: ScenarioCo }), initPhase: DashboardInitPhase.NotStarted, isInitSlow: false, + initError: null, initDashboard: jest.fn(), notifyApp: mockToolkitActionCreator(notifyApp), cleanUpDashboardAndVariables: jest.fn(), diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 4a9eb748d96..40d0389617e 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { css } from 'emotion'; import { hot } from 'react-hot-loader'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { locationService } from '@grafana/runtime'; import { selectors } from '@grafana/e2e-selectors'; import { CustomScrollbar, ScrollbarPosition, stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; @@ -14,8 +14,8 @@ import { DashboardSettings } from '../components/DashboardSettings'; import { PanelEditor } from '../components/PanelEditor/PanelEditor'; import { initDashboard } from '../state/initDashboard'; import { notifyApp } from 'app/core/actions'; -import { DashboardInitError, DashboardInitPhase, KioskMode, StoreState } from 'app/types'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; +import { KioskMode, StoreState } from 'app/types'; +import { PanelModel } from 'app/features/dashboard/state'; import { PanelInspector } from '../components/Inspector/PanelInspector'; import { SubMenu } from '../components/SubMenu/SubMenu'; import { cleanUpDashboardAndVariables } from '../state/actions'; @@ -50,21 +50,32 @@ type DashboardPageRouteSearchParams = { refresh?: string; }; -export interface Props - extends Themeable2, - GrafanaRouteComponentProps { - initPhase: DashboardInitPhase; - isInitSlow: boolean; - dashboard: DashboardModel | null; - initError?: DashboardInitError; - initDashboard: typeof initDashboard; - cleanUpDashboardAndVariables: typeof cleanUpDashboardAndVariables; - notifyApp: typeof notifyApp; +export const mapStateToProps = (state: StoreState) => ({ + initPhase: state.dashboard.initPhase, + isInitSlow: state.dashboard.isInitSlow, + initError: state.dashboard.initError, + dashboard: state.dashboard.getModel(), +}); + +const mapDispatchToProps = { + initDashboard, + cleanUpDashboardAndVariables, + notifyApp, + cancelVariables, + templateVarsChangedInUrl, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +interface OwnProps { isPanelEditorOpen?: boolean; - cancelVariables: typeof cancelVariables; - templateVarsChangedInUrl: typeof templateVarsChangedInUrl; } +export type Props = Themeable2 & + GrafanaRouteComponentProps & + ConnectedProps & + OwnProps; + export interface State { editPanel: PanelModel | null; viewPanel: PanelModel | null; @@ -366,21 +377,6 @@ export class UnthemedDashboardPage extends PureComponent { } } -export const mapStateToProps = (state: StoreState) => ({ - initPhase: state.dashboard.initPhase, - isInitSlow: state.dashboard.isInitSlow, - initError: state.dashboard.initError, - dashboard: state.dashboard.getModel(), -}); - -const mapDispatchToProps = { - initDashboard, - cleanUpDashboardAndVariables, - notifyApp, - cancelVariables, - templateVarsChangedInUrl, -}; - /* * Styles */ @@ -413,4 +409,4 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, kioskMode) => { export const DashboardPage = withTheme2(UnthemedDashboardPage); DashboardPage.displayName = 'DashboardPage'; -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DashboardPage)); +export default hot(module)(connector(DashboardPage)); diff --git a/public/app/features/dashboard/containers/SoloPanelPage.tsx b/public/app/features/dashboard/containers/SoloPanelPage.tsx index a2361dc71ed..36bdbc44aa7 100644 --- a/public/app/features/dashboard/containers/SoloPanelPage.tsx +++ b/public/app/features/dashboard/containers/SoloPanelPage.tsx @@ -1,11 +1,11 @@ import React, { Component } from 'react'; import { hot } from 'react-hot-loader'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import AutoSizer from 'react-virtualized-auto-sizer'; import { DashboardPanel } from '../dashgrid/DashboardPanel'; import { initDashboard } from '../state/initDashboard'; import { StoreState } from 'app/types'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; +import { PanelModel } from 'app/features/dashboard/state'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; export interface DashboardPageRouteParams { @@ -14,10 +14,18 @@ export interface DashboardPageRouteParams { slug?: string; } -export interface Props extends GrafanaRouteComponentProps { - initDashboard: typeof initDashboard; - dashboard: DashboardModel | null; -} +const mapStateToProps = (state: StoreState) => ({ + dashboard: state.dashboard.getModel(), +}); + +const mapDispatchToProps = { + initDashboard, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +export type Props = GrafanaRouteComponentProps & + ConnectedProps; export interface State { panel: PanelModel | null; @@ -103,12 +111,4 @@ export class SoloPanelPage extends Component { } } -const mapStateToProps = (state: StoreState) => ({ - dashboard: state.dashboard.getModel(), -}); - -const mapDispatchToProps = { - initDashboard, -}; - -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(SoloPanelPage)); +export default hot(module)(connector(SoloPanelPage)); diff --git a/public/app/features/datasources/DataSourcesListPage.tsx b/public/app/features/datasources/DataSourcesListPage.tsx index 77ccb062f6d..fbfb1cf8c66 100644 --- a/public/app/features/datasources/DataSourcesListPage.tsx +++ b/public/app/features/datasources/DataSourcesListPage.tsx @@ -1,6 +1,6 @@ // Libraries import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { hot } from 'react-hot-loader'; // Components import Page from 'app/core/components/Page/Page'; @@ -8,7 +8,6 @@ import PageActionBar from 'app/core/components/PageActionBar/PageActionBar'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import DataSourcesList from './DataSourcesList'; // Types -import { DataSourceSettings, NavModel, LayoutMode } from '@grafana/data'; import { IconName } from '@grafana/ui'; import { StoreState } from 'app/types'; // Actions @@ -23,18 +22,27 @@ import { } from './state/selectors'; import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/reducers'; -export interface Props { - navModel: NavModel; - dataSources: DataSourceSettings[]; - dataSourcesCount: number; - layoutMode: LayoutMode; - searchQuery: string; - hasFetched: boolean; - loadDataSources: typeof loadDataSources; - setDataSourcesLayoutMode: typeof setDataSourcesLayoutMode; - setDataSourcesSearchQuery: typeof setDataSourcesSearchQuery; +function mapStateToProps(state: StoreState) { + return { + navModel: getNavModel(state.navIndex, 'datasources'), + dataSources: getDataSources(state.dataSources), + layoutMode: getDataSourcesLayoutMode(state.dataSources), + dataSourcesCount: getDataSourcesCount(state.dataSources), + searchQuery: getDataSourcesSearchQuery(state.dataSources), + hasFetched: state.dataSources.hasFetched, + }; } +const mapDispatchToProps = { + loadDataSources, + setDataSourcesSearchQuery, + setDataSourcesLayoutMode, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +export type Props = ConnectedProps; + const emptyListModel = { title: 'No data sources defined', buttonIcon: 'database' as IconName, @@ -89,21 +97,4 @@ export class DataSourcesListPage extends PureComponent { } } -function mapStateToProps(state: StoreState) { - return { - navModel: getNavModel(state.navIndex, 'datasources'), - dataSources: getDataSources(state.dataSources), - layoutMode: getDataSourcesLayoutMode(state.dataSources), - dataSourcesCount: getDataSourcesCount(state.dataSources), - searchQuery: getDataSourcesSearchQuery(state.dataSources), - hasFetched: state.dataSources.hasFetched, - }; -} - -const mapDispatchToProps = { - loadDataSources, - setDataSourcesSearchQuery, - setDataSourcesLayoutMode, -}; - -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourcesListPage)); +export default hot(module)(connector(DataSourcesListPage)); diff --git a/public/app/features/datasources/NewDataSourcePage.tsx b/public/app/features/datasources/NewDataSourcePage.tsx index 249e0cfe157..24941717b0a 100644 --- a/public/app/features/datasources/NewDataSourcePage.tsx +++ b/public/app/features/datasources/NewDataSourcePage.tsx @@ -1,12 +1,12 @@ import React, { FC, PureComponent } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { hot } from 'react-hot-loader'; import { DataSourcePluginMeta, NavModel } from '@grafana/data'; import { Button, LinkButton, List, PluginSignatureBadge } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; import Page from 'app/core/components/Page/Page'; -import { DataSourcePluginCategory, StoreState } from 'app/types'; +import { StoreState } from 'app/types'; import { addDataSource, loadDataSourcePlugins } from './state/actions'; import { getDataSourcePlugins } from './state/selectors'; import { FilterInput } from 'app/core/components/FilterInput/FilterInput'; @@ -14,17 +14,26 @@ import { setDataSourceTypeSearchQuery } from './state/reducers'; import { Card } from 'app/core/components/Card/Card'; import { PluginsErrorsInfo } from '../plugins/PluginsErrorsInfo'; -export interface Props { - navModel: NavModel; - plugins: DataSourcePluginMeta[]; - categories: DataSourcePluginCategory[]; - isLoading: boolean; - addDataSource: typeof addDataSource; - loadDataSourcePlugins: typeof loadDataSourcePlugins; - searchQuery: string; - setDataSourceTypeSearchQuery: typeof setDataSourceTypeSearchQuery; +function mapStateToProps(state: StoreState) { + return { + navModel: getNavModel(), + plugins: getDataSourcePlugins(state.dataSources), + searchQuery: state.dataSources.dataSourceTypeSearchQuery, + categories: state.dataSources.categories, + isLoading: state.dataSources.isLoadingDataSources, + }; } +const mapDispatchToProps = { + addDataSource, + loadDataSourcePlugins, + setDataSourceTypeSearchQuery, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +type Props = ConnectedProps; + class NewDataSourcePage extends PureComponent { componentDidMount() { this.props.loadDataSourcePlugins(); @@ -170,20 +179,4 @@ export function getNavModel(): NavModel { }; } -function mapStateToProps(state: StoreState) { - return { - navModel: getNavModel(), - plugins: getDataSourcePlugins(state.dataSources), - searchQuery: state.dataSources.dataSourceTypeSearchQuery, - categories: state.dataSources.categories, - isLoading: state.dataSources.isLoadingDataSources, - }; -} - -const mapDispatchToProps = { - addDataSource, - loadDataSourcePlugins, - setDataSourceTypeSearchQuery, -}; - -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(NewDataSourcePage)); +export default hot(module)(connector(NewDataSourcePage)); diff --git a/public/app/features/explore/RichHistory/RichHistory.tsx b/public/app/features/explore/RichHistory/RichHistory.tsx index 3acd197e6ee..1478b3dd1d6 100644 --- a/public/app/features/explore/RichHistory/RichHistory.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.tsx @@ -29,7 +29,7 @@ export const sortOrderOptions = [ export interface RichHistoryProps extends Themeable { richHistory: RichHistoryQuery[]; - activeDatasourceInstance: string; + activeDatasourceInstance?: string; firstTab: Tabs; exploreId: ExploreId; height: number; @@ -57,11 +57,13 @@ class UnThemedRichHistory extends PureComponent { - this.setState({ - retentionPeriod: retentionPeriod.value, - }); - store.set(RICH_HISTORY_SETTING_KEYS.retentionPeriod, retentionPeriod.value); + onChangeRetentionPeriod = (retentionPeriod: SelectableValue) => { + if (retentionPeriod.value !== undefined) { + this.setState({ + retentionPeriod: retentionPeriod.value, + }); + store.set(RICH_HISTORY_SETTING_KEYS.retentionPeriod, retentionPeriod.value); + } }; toggleStarredTabAsFirstTab = () => { diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.tsx index f60601313a5..452305c2171 100644 --- a/public/app/features/explore/RichHistory/RichHistoryCard.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryCard.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { hot } from 'react-hot-loader'; import { css, cx } from '@emotion/css'; import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui'; @@ -20,17 +20,31 @@ import { changeDatasource } from '../state/datasource'; import { setQueries } from '../state/query'; import { ShowConfirmModalEvent } from '../../../types/events'; -export interface Props { +function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { + const explore = state.explore; + const { datasourceInstance } = explore[exploreId]!; + return { + exploreId, + datasourceInstance, + }; +} + +const mapDispatchToProps = { + changeDatasource, + updateRichHistory, + setQueries, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +interface OwnProps { query: RichHistoryQuery; dsImg: string; isRemoved: boolean; - changeDatasource: typeof changeDatasource; - updateRichHistory: typeof updateRichHistory; - setQueries: typeof setQueries; - exploreId: ExploreId; - datasourceInstance: DataSourceApi; } +export type Props = ConnectedProps & OwnProps; + const getStyles = stylesFactory((theme: GrafanaTheme, isRemoved: boolean) => { /* Hard-coded value so all buttons and icons on right side of card are aligned */ const rigtColumnWidth = '240px'; @@ -304,19 +318,4 @@ export function RichHistoryCard(props: Props) { ); } -function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { - const explore = state.explore; - const { datasourceInstance } = explore[exploreId]!; - return { - exploreId, - datasourceInstance, - }; -} - -const mapDispatchToProps = { - changeDatasource, - updateRichHistory, - setQueries, -}; - -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(RichHistoryCard)); +export default hot(module)(connector(RichHistoryCard)); diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx index 70eb290118d..80ef6407b84 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx @@ -1,6 +1,6 @@ // Libraries import React, { useState } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { hot } from 'react-hot-loader'; // Services & Utils @@ -9,7 +9,7 @@ import { RICH_HISTORY_SETTING_KEYS } from 'app/core/utils/richHistory'; // Types import { ExploreItemState, StoreState } from 'app/types'; -import { ExploreId, RichHistoryQuery } from 'app/types/explore'; +import { ExploreId } from 'app/types/explore'; // Components, enums import { RichHistory, Tabs } from './RichHistory'; @@ -18,15 +18,34 @@ import { RichHistory, Tabs } from './RichHistory'; import { deleteRichHistory } from '../state/history'; import { ExploreDrawer } from '../ExploreDrawer'; -export interface Props { +function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { + const explore = state.explore; + // @ts-ignore + const item: ExploreItemState = explore[exploreId]; + const { datasourceInstance } = item; + const firstTab = store.getBool(RICH_HISTORY_SETTING_KEYS.starredTabAsFirstTab, false) + ? Tabs.Starred + : Tabs.RichHistory; + const { richHistory } = explore; + return { + richHistory, + firstTab, + activeDatasourceInstance: datasourceInstance?.name, + }; +} + +const mapDispatchToProps = { + deleteRichHistory, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +interface OwnProps { width: number; exploreId: ExploreId; - activeDatasourceInstance: string; - richHistory: RichHistoryQuery[]; - firstTab: Tabs; - deleteRichHistory: typeof deleteRichHistory; onClose: () => void; } +export type Props = ConnectedProps & OwnProps; export function RichHistoryContainer(props: Props) { const [height, setHeight] = useState(400); @@ -53,24 +72,4 @@ export function RichHistoryContainer(props: Props) { ); } -function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { - const explore = state.explore; - // @ts-ignore - const item: ExploreItemState = explore[exploreId]; - const { datasourceInstance } = item; - const firstTab = store.getBool(RICH_HISTORY_SETTING_KEYS.starredTabAsFirstTab, false) - ? Tabs.Starred - : Tabs.RichHistory; - const { richHistory } = explore; - return { - richHistory, - firstTab, - activeDatasourceInstance: datasourceInstance?.name, - }; -} - -const mapDispatchToProps = { - deleteRichHistory, -}; - -export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(RichHistoryContainer)); +export default hot(module)(connector(RichHistoryContainer)); diff --git a/public/app/features/explore/RichHistory/RichHistorySettings.tsx b/public/app/features/explore/RichHistory/RichHistorySettings.tsx index 8d73366a96e..e5ab8048f31 100644 --- a/public/app/features/explore/RichHistory/RichHistorySettings.tsx +++ b/public/app/features/explore/RichHistory/RichHistorySettings.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { css } from '@emotion/css'; import { stylesFactory, useTheme, Select, Button, Switch, Field } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; +import { GrafanaTheme, SelectableValue } from '@grafana/data'; import appEvents from 'app/core/app_events'; import { ShowConfirmModalEvent } from '../../../types/events'; import { dispatch } from 'app/store/store'; @@ -12,7 +12,7 @@ export interface RichHistorySettingsProps { retentionPeriod: number; starredTabAsFirstTab: boolean; activeDatasourceOnly: boolean; - onChangeRetentionPeriod: (option: { label: string; value: number }) => void; + onChangeRetentionPeriod: (option: SelectableValue) => void; toggleStarredTabAsFirstTab: () => void; toggleactiveDatasourceOnly: () => void; deleteRichHistory: () => void; diff --git a/public/app/features/folders/components/NewDashboardsFolder.tsx b/public/app/features/folders/components/NewDashboardsFolder.tsx index 068f7940e6f..bce9eda3468 100644 --- a/public/app/features/folders/components/NewDashboardsFolder.tsx +++ b/public/app/features/folders/components/NewDashboardsFolder.tsx @@ -1,6 +1,5 @@ import React, { PureComponent } from 'react'; -import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; -import { NavModel } from '@grafana/data'; +import { connect, ConnectedProps } from 'react-redux'; import { Button, Input, Form, Field } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { createNewFolder } from '../state/actions'; @@ -8,15 +7,17 @@ import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; import validationSrv from '../../manage-dashboards/services/ValidationSrv'; -interface OwnProps {} +const mapStateToProps = (state: StoreState) => ({ + navModel: getNavModel(state.navIndex, 'manage-dashboards'), +}); -interface ConnectedProps { - navModel: NavModel; -} +const mapDispatchToProps = { + createNewFolder, +}; -interface DispatchProps { - createNewFolder: typeof createNewFolder; -} +const connector = connect(mapStateToProps, mapDispatchToProps); + +interface OwnProps {} interface FormModel { folderName: string; @@ -24,7 +25,7 @@ interface FormModel { const initialFormModel: FormModel = { folderName: '' }; -type Props = OwnProps & ConnectedProps & DispatchProps; +type Props = OwnProps & ConnectedProps; export class NewDashboardsFolder extends PureComponent { onSubmit = (formData: FormModel) => { @@ -72,12 +73,4 @@ export class NewDashboardsFolder extends PureComponent { } } -const mapStateToProps: MapStateToProps = (state) => ({ - navModel: getNavModel(state.navIndex, 'manage-dashboards'), -}); - -const mapDispatchToProps: MapDispatchToProps = { - createNewFolder, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(NewDashboardsFolder); +export default connector(NewDashboardsFolder); diff --git a/public/app/features/teams/TeamMemberRow.tsx b/public/app/features/teams/TeamMemberRow.tsx index 7485baa7fc5..d59ef6985f3 100644 --- a/public/app/features/teams/TeamMemberRow.tsx +++ b/public/app/features/teams/TeamMemberRow.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { LegacyForms, DeleteButton } from '@grafana/ui'; const { Select } = LegacyForms; import { SelectableValue } from '@grafana/data'; @@ -9,14 +9,20 @@ import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { updateTeamMember, removeTeamMember } from './state/actions'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; -export interface Props { +const mapDispatchToProps = { + removeTeamMember, + updateTeamMember, +}; + +const connector = connect(null, mapDispatchToProps); + +interface OwnProps { member: TeamMember; syncEnabled: boolean; editorsCanAdmin: boolean; signedInUserIsTeamAdmin: boolean; - removeTeamMember: typeof removeTeamMember; - updateTeamMember: typeof updateTeamMember; } +export type Props = ConnectedProps & OwnProps; export class TeamMemberRow extends PureComponent { constructor(props: Props) { @@ -97,13 +103,4 @@ export class TeamMemberRow extends PureComponent { } } -function mapStateToProps(state: any) { - return {}; -} - -const mapDispatchToProps = { - removeTeamMember, - updateTeamMember, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(TeamMemberRow); +export default connector(TeamMemberRow); diff --git a/public/app/features/teams/TeamMembers.tsx b/public/app/features/teams/TeamMembers.tsx index af1d812fc69..5454998bdea 100644 --- a/public/app/features/teams/TeamMembers.tsx +++ b/public/app/features/teams/TeamMembers.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; import { UserPicker } from 'app/core/components/Select/UserPicker'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; @@ -9,23 +9,35 @@ import { getSearchMemberQuery, isSignedInUserTeamAdmin } from './state/selectors import { FilterInput } from 'app/core/components/FilterInput/FilterInput'; import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { config } from 'app/core/config'; -import { contextSrv, User as SignedInUser } from 'app/core/services/context_srv'; +import { contextSrv } from 'app/core/services/context_srv'; import TeamMemberRow from './TeamMemberRow'; import { setSearchMemberQuery } from './state/reducers'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; import { Button } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; -export interface Props { +function mapStateToProps(state: any) { + return { + searchMemberQuery: getSearchMemberQuery(state.team), + editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests, + signedInUser: contextSrv.user, // this makes the feature toggle mockable/controllable from tests, + }; +} + +const mapDispatchToProps = { + addTeamMember, + setSearchMemberQuery, +}; + +const connector = connect(mapStateToProps, mapDispatchToProps); + +interface OwnProps { members: TeamMember[]; - searchMemberQuery: string; - addTeamMember: typeof addTeamMember; - setSearchMemberQuery: typeof setSearchMemberQuery; syncEnabled: boolean; - editorsCanAdmin: boolean; - signedInUser: SignedInUser; } +export type Props = ConnectedProps & OwnProps; + export interface State { isAdding: boolean; newTeamMember?: SelectableValue | null; @@ -133,17 +145,4 @@ export class TeamMembers extends PureComponent { } } -function mapStateToProps(state: any) { - return { - searchMemberQuery: getSearchMemberQuery(state.team), - editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests, - signedInUser: contextSrv.user, // this makes the feature toggle mockable/controllable from tests, - }; -} - -const mapDispatchToProps = { - addTeamMember, - setSearchMemberQuery, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(TeamMembers); +export default connector(TeamMembers); diff --git a/public/app/features/teams/TeamSettings.tsx b/public/app/features/teams/TeamSettings.tsx index 9a8e6c18f36..eaade3c3986 100644 --- a/public/app/features/teams/TeamSettings.tsx +++ b/public/app/features/teams/TeamSettings.tsx @@ -1,15 +1,21 @@ import React, { FC } from 'react'; -import { connect } from 'react-redux'; +import { connect, ConnectedProps } from 'react-redux'; import { Input, Field, Form, Button, FieldSet, VerticalGroup } from '@grafana/ui'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; import { updateTeam } from './state/actions'; import { Team } from 'app/types'; -export interface Props { +const mapDispatchToProps = { + updateTeam, +}; + +const connector = connect(null, mapDispatchToProps); + +interface OwnProps { team: Team; - updateTeam: typeof updateTeam; } +export type Props = ConnectedProps & OwnProps; export const TeamSettings: FC = ({ team, updateTeam }) => { return ( @@ -43,8 +49,4 @@ export const TeamSettings: FC = ({ team, updateTeam }) => { ); }; -const mapDispatchToProps = { - updateTeam, -}; - -export default connect(null, mapDispatchToProps)(TeamSettings); +export default connector(TeamSettings); diff --git a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx index a74b50f7517..8a46e71b2f7 100644 --- a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx @@ -32,7 +32,7 @@ export const MetricPicker = ({ options, onChange, className, value }: Props) => options={toOptions(options)} onChange={onChange} placeholder="Select Metric" - value={!!selectedOption ? toOption(selectedOption) : null} + value={!!selectedOption ? toOption(selectedOption) : undefined} /> ); }; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx index efa666958ef..1e9ab8c9862 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx @@ -94,7 +94,7 @@ describe('Metric Editor', () => { const getFields: ElasticDatasource['getFields'] = jest.fn(() => from([[]])); - const wrapper = ({ children }: { children: ReactNode }) => ( + const wrapper = ({ children }: { children?: ReactNode }) => ( > = [ { value: 'range', label: 'Range', description: 'Run query over a range of time.' }, { value: 'instant', diff --git a/public/app/plugins/panel/geomap/dims/editors/ScaleDimensionEditor.tsx b/public/app/plugins/panel/geomap/dims/editors/ScaleDimensionEditor.tsx index babd58c9060..8d16ad617f8 100644 --- a/public/app/plugins/panel/geomap/dims/editors/ScaleDimensionEditor.tsx +++ b/public/app/plugins/panel/geomap/dims/editors/ScaleDimensionEditor.tsx @@ -58,31 +58,37 @@ export const ScaleDimensionEditor: FC { - validateAndDoChange({ - ...value, - min, - }); + (min?: number) => { + if (min !== undefined) { + validateAndDoChange({ + ...value, + min, + }); + } }, [validateAndDoChange, value] ); const onMaxChange = useCallback( - (max: number) => { - validateAndDoChange({ - ...value, - max, - }); + (max?: number) => { + if (max !== undefined) { + validateAndDoChange({ + ...value, + max, + }); + } }, [validateAndDoChange, value] ); const onValueChange = useCallback( - (fixed: number) => { - validateAndDoChange({ - ...value, - fixed, - }); + (fixed?: number) => { + if (fixed !== undefined) { + validateAndDoChange({ + ...value, + fixed, + }); + } }, [validateAndDoChange, value] ); diff --git a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx index 20616bf8217..ded8d7eda37 100644 --- a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx @@ -147,7 +147,7 @@ export const ContextMenuPlugin: React.FC = ({ items: i.items.map((j) => { return { ...j, - onClick: (e: React.SyntheticEvent) => { + onClick: (e?: React.SyntheticEvent) => { if (!coords) { return; } diff --git a/scripts/ci-check-strict.sh b/scripts/ci-check-strict.sh index 1ee94a831f4..d1757025776 100755 --- a/scripts/ci-check-strict.sh +++ b/scripts/ci-check-strict.sh @@ -3,7 +3,7 @@ set -e echo -e "Collecting code stats (typescript errors & more)" -ERROR_COUNT_LIMIT=157 +ERROR_COUNT_LIMIT=136 ERROR_COUNT="$(./node_modules/.bin/tsc --project tsconfig.json --noEmit --strict true | grep -oP 'Found \K(\d+)')" if [ "$ERROR_COUNT" -gt $ERROR_COUNT_LIMIT ]; then