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...
pull/37144/head
Ashley Harrison 4 years ago committed by GitHub
parent 2b51e94537
commit 75ff031789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      public/app/features/dashboard/components/DashNav/DashNav.tsx
  2. 1
      public/app/features/dashboard/containers/DashboardPage.test.tsx
  3. 58
      public/app/features/dashboard/containers/DashboardPage.tsx
  4. 30
      public/app/features/dashboard/containers/SoloPanelPage.tsx
  5. 51
      public/app/features/datasources/DataSourcesListPage.tsx
  6. 49
      public/app/features/datasources/NewDataSourcePage.tsx
  7. 14
      public/app/features/explore/RichHistory/RichHistory.tsx
  8. 45
      public/app/features/explore/RichHistory/RichHistoryCard.tsx
  9. 55
      public/app/features/explore/RichHistory/RichHistoryContainer.tsx
  10. 4
      public/app/features/explore/RichHistory/RichHistorySettings.tsx
  11. 31
      public/app/features/folders/components/NewDashboardsFolder.tsx
  12. 25
      public/app/features/teams/TeamMemberRow.tsx
  13. 43
      public/app/features/teams/TeamMembers.tsx
  14. 18
      public/app/features/teams/TeamSettings.tsx
  15. 2
      public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx
  16. 2
      public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx
  17. 3
      public/app/plugins/datasource/loki/components/LokiOptionFields.tsx
  18. 36
      public/app/plugins/panel/geomap/dims/editors/ScaleDimensionEditor.tsx
  19. 2
      public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx
  20. 2
      scripts/ci-check-strict.sh

@ -1,6 +1,6 @@
// Libaries // Libaries
import React, { PureComponent, FC, ReactNode } from 'react'; import React, { PureComponent, FC, ReactNode } from 'react';
import { connect, MapDispatchToProps } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
// Utils & Services // Utils & Services
import { playlistSrv } from 'app/features/playlist/PlaylistSrv'; import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
// Components // Components
@ -12,13 +12,19 @@ import { locationUtil, textUtil } from '@grafana/data';
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
// Types // Types
import { DashboardModel } from '../../state'; import { DashboardModel } from '../../state';
import { KioskMode, StoreState } from 'app/types'; import { KioskMode } from 'app/types';
import { ShareModal } from 'app/features/dashboard/components/ShareModal'; import { ShareModal } from 'app/features/dashboard/components/ShareModal';
import { SaveDashboardModalProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardModalProxy'; import { SaveDashboardModalProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardModalProxy';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
import { toggleKioskMode } from 'app/core/navigation/kiosk'; import { toggleKioskMode } from 'app/core/navigation/kiosk';
import { getDashboardSrv } from '../../services/DashboardSrv'; import { getDashboardSrv } from '../../services/DashboardSrv';
const mapDispatchToProps = {
updateTimeZoneForSession,
};
const connector = connect(null, mapDispatchToProps);
export interface OwnProps { export interface OwnProps {
dashboard: DashboardModel; dashboard: DashboardModel;
isFullscreen: boolean; isFullscreen: boolean;
@ -29,10 +35,6 @@ export interface OwnProps {
onAddPanel: () => void; onAddPanel: () => void;
} }
interface DispatchProps {
updateTimeZoneForSession: typeof updateTimeZoneForSession;
}
interface DashNavButtonModel { interface DashNavButtonModel {
show: (props: Props) => boolean; show: (props: Props) => boolean;
component: FC<Partial<Props>>; component: FC<Partial<Props>>;
@ -50,7 +52,7 @@ export function addCustomRightAction(content: DashNavButtonModel) {
customRightActions.push(content); customRightActions.push(content);
} }
type Props = OwnProps & DispatchProps; type Props = OwnProps & ConnectedProps<typeof connector>;
class DashNav extends PureComponent<Props> { class DashNav extends PureComponent<Props> {
constructor(props: Props) { constructor(props: Props) {
@ -263,10 +265,4 @@ class DashNav extends PureComponent<Props> {
} }
} }
const mapStateToProps = (state: StoreState) => ({}); export default connector(DashNav);
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
updateTimeZoneForSession,
};
export default connect(mapStateToProps, mapDispatchToProps)(DashNav);

@ -78,6 +78,7 @@ function dashboardPageScenario(description: string, scenarioFn: (ctx: ScenarioCo
}), }),
initPhase: DashboardInitPhase.NotStarted, initPhase: DashboardInitPhase.NotStarted,
isInitSlow: false, isInitSlow: false,
initError: null,
initDashboard: jest.fn(), initDashboard: jest.fn(),
notifyApp: mockToolkitActionCreator(notifyApp), notifyApp: mockToolkitActionCreator(notifyApp),
cleanUpDashboardAndVariables: jest.fn(), cleanUpDashboardAndVariables: jest.fn(),

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { css } from 'emotion'; import { css } from 'emotion';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { CustomScrollbar, ScrollbarPosition, stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; 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 { PanelEditor } from '../components/PanelEditor/PanelEditor';
import { initDashboard } from '../state/initDashboard'; import { initDashboard } from '../state/initDashboard';
import { notifyApp } from 'app/core/actions'; import { notifyApp } from 'app/core/actions';
import { DashboardInitError, DashboardInitPhase, KioskMode, StoreState } from 'app/types'; import { KioskMode, StoreState } from 'app/types';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { PanelModel } from 'app/features/dashboard/state';
import { PanelInspector } from '../components/Inspector/PanelInspector'; import { PanelInspector } from '../components/Inspector/PanelInspector';
import { SubMenu } from '../components/SubMenu/SubMenu'; import { SubMenu } from '../components/SubMenu/SubMenu';
import { cleanUpDashboardAndVariables } from '../state/actions'; import { cleanUpDashboardAndVariables } from '../state/actions';
@ -50,21 +50,32 @@ type DashboardPageRouteSearchParams = {
refresh?: string; refresh?: string;
}; };
export interface Props export const mapStateToProps = (state: StoreState) => ({
extends Themeable2, initPhase: state.dashboard.initPhase,
GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams> { isInitSlow: state.dashboard.isInitSlow,
initPhase: DashboardInitPhase; initError: state.dashboard.initError,
isInitSlow: boolean; dashboard: state.dashboard.getModel(),
dashboard: DashboardModel | null; });
initError?: DashboardInitError;
initDashboard: typeof initDashboard; const mapDispatchToProps = {
cleanUpDashboardAndVariables: typeof cleanUpDashboardAndVariables; initDashboard,
notifyApp: typeof notifyApp; cleanUpDashboardAndVariables,
notifyApp,
cancelVariables,
templateVarsChangedInUrl,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
interface OwnProps {
isPanelEditorOpen?: boolean; isPanelEditorOpen?: boolean;
cancelVariables: typeof cancelVariables;
templateVarsChangedInUrl: typeof templateVarsChangedInUrl;
} }
export type Props = Themeable2 &
GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams> &
ConnectedProps<typeof connector> &
OwnProps;
export interface State { export interface State {
editPanel: PanelModel | null; editPanel: PanelModel | null;
viewPanel: PanelModel | null; viewPanel: PanelModel | null;
@ -366,21 +377,6 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
} }
} }
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 * Styles
*/ */
@ -413,4 +409,4 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, kioskMode) => {
export const DashboardPage = withTheme2(UnthemedDashboardPage); export const DashboardPage = withTheme2(UnthemedDashboardPage);
DashboardPage.displayName = 'DashboardPage'; DashboardPage.displayName = 'DashboardPage';
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DashboardPage)); export default hot(module)(connector(DashboardPage));

@ -1,11 +1,11 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { hot } from 'react-hot-loader'; 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 AutoSizer from 'react-virtualized-auto-sizer';
import { DashboardPanel } from '../dashgrid/DashboardPanel'; import { DashboardPanel } from '../dashgrid/DashboardPanel';
import { initDashboard } from '../state/initDashboard'; import { initDashboard } from '../state/initDashboard';
import { StoreState } from 'app/types'; 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'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
export interface DashboardPageRouteParams { export interface DashboardPageRouteParams {
@ -14,10 +14,18 @@ export interface DashboardPageRouteParams {
slug?: string; slug?: string;
} }
export interface Props extends GrafanaRouteComponentProps<DashboardPageRouteParams, { panelId: string }> { const mapStateToProps = (state: StoreState) => ({
initDashboard: typeof initDashboard; dashboard: state.dashboard.getModel(),
dashboard: DashboardModel | null; });
}
const mapDispatchToProps = {
initDashboard,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export type Props = GrafanaRouteComponentProps<DashboardPageRouteParams, { panelId: string }> &
ConnectedProps<typeof connector>;
export interface State { export interface State {
panel: PanelModel | null; panel: PanelModel | null;
@ -103,12 +111,4 @@ export class SoloPanelPage extends Component<Props, State> {
} }
} }
const mapStateToProps = (state: StoreState) => ({ export default hot(module)(connector(SoloPanelPage));
dashboard: state.dashboard.getModel(),
});
const mapDispatchToProps = {
initDashboard,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(SoloPanelPage));

@ -1,6 +1,6 @@
// Libraries // Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
// Components // Components
import Page from 'app/core/components/Page/Page'; 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 EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import DataSourcesList from './DataSourcesList'; import DataSourcesList from './DataSourcesList';
// Types // Types
import { DataSourceSettings, NavModel, LayoutMode } from '@grafana/data';
import { IconName } from '@grafana/ui'; import { IconName } from '@grafana/ui';
import { StoreState } from 'app/types'; import { StoreState } from 'app/types';
// Actions // Actions
@ -23,18 +22,27 @@ import {
} from './state/selectors'; } from './state/selectors';
import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/reducers'; import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/reducers';
export interface Props { function mapStateToProps(state: StoreState) {
navModel: NavModel; return {
dataSources: DataSourceSettings[]; navModel: getNavModel(state.navIndex, 'datasources'),
dataSourcesCount: number; dataSources: getDataSources(state.dataSources),
layoutMode: LayoutMode; layoutMode: getDataSourcesLayoutMode(state.dataSources),
searchQuery: string; dataSourcesCount: getDataSourcesCount(state.dataSources),
hasFetched: boolean; searchQuery: getDataSourcesSearchQuery(state.dataSources),
loadDataSources: typeof loadDataSources; hasFetched: state.dataSources.hasFetched,
setDataSourcesLayoutMode: typeof setDataSourcesLayoutMode; };
setDataSourcesSearchQuery: typeof setDataSourcesSearchQuery;
} }
const mapDispatchToProps = {
loadDataSources,
setDataSourcesSearchQuery,
setDataSourcesLayoutMode,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export type Props = ConnectedProps<typeof connector>;
const emptyListModel = { const emptyListModel = {
title: 'No data sources defined', title: 'No data sources defined',
buttonIcon: 'database' as IconName, buttonIcon: 'database' as IconName,
@ -89,21 +97,4 @@ export class DataSourcesListPage extends PureComponent<Props> {
} }
} }
function mapStateToProps(state: StoreState) { export default hot(module)(connector(DataSourcesListPage));
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));

@ -1,12 +1,12 @@
import React, { FC, PureComponent } from 'react'; import React, { FC, PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { DataSourcePluginMeta, NavModel } from '@grafana/data'; import { DataSourcePluginMeta, NavModel } from '@grafana/data';
import { Button, LinkButton, List, PluginSignatureBadge } from '@grafana/ui'; import { Button, LinkButton, List, PluginSignatureBadge } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import Page from 'app/core/components/Page/Page'; 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 { addDataSource, loadDataSourcePlugins } from './state/actions';
import { getDataSourcePlugins } from './state/selectors'; import { getDataSourcePlugins } from './state/selectors';
import { FilterInput } from 'app/core/components/FilterInput/FilterInput'; 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 { Card } from 'app/core/components/Card/Card';
import { PluginsErrorsInfo } from '../plugins/PluginsErrorsInfo'; import { PluginsErrorsInfo } from '../plugins/PluginsErrorsInfo';
export interface Props { function mapStateToProps(state: StoreState) {
navModel: NavModel; return {
plugins: DataSourcePluginMeta[]; navModel: getNavModel(),
categories: DataSourcePluginCategory[]; plugins: getDataSourcePlugins(state.dataSources),
isLoading: boolean; searchQuery: state.dataSources.dataSourceTypeSearchQuery,
addDataSource: typeof addDataSource; categories: state.dataSources.categories,
loadDataSourcePlugins: typeof loadDataSourcePlugins; isLoading: state.dataSources.isLoadingDataSources,
searchQuery: string; };
setDataSourceTypeSearchQuery: typeof setDataSourceTypeSearchQuery;
} }
const mapDispatchToProps = {
addDataSource,
loadDataSourcePlugins,
setDataSourceTypeSearchQuery,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
type Props = ConnectedProps<typeof connector>;
class NewDataSourcePage extends PureComponent<Props> { class NewDataSourcePage extends PureComponent<Props> {
componentDidMount() { componentDidMount() {
this.props.loadDataSourcePlugins(); this.props.loadDataSourcePlugins();
@ -170,20 +179,4 @@ export function getNavModel(): NavModel {
}; };
} }
function mapStateToProps(state: StoreState) { export default hot(module)(connector(NewDataSourcePage));
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));

@ -29,7 +29,7 @@ export const sortOrderOptions = [
export interface RichHistoryProps extends Themeable { export interface RichHistoryProps extends Themeable {
richHistory: RichHistoryQuery[]; richHistory: RichHistoryQuery[];
activeDatasourceInstance: string; activeDatasourceInstance?: string;
firstTab: Tabs; firstTab: Tabs;
exploreId: ExploreId; exploreId: ExploreId;
height: number; height: number;
@ -57,11 +57,13 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
}; };
} }
onChangeRetentionPeriod = (retentionPeriod: { label: string; value: number }) => { onChangeRetentionPeriod = (retentionPeriod: SelectableValue<number>) => {
this.setState({ if (retentionPeriod.value !== undefined) {
retentionPeriod: retentionPeriod.value, this.setState({
}); retentionPeriod: retentionPeriod.value,
store.set(RICH_HISTORY_SETTING_KEYS.retentionPeriod, retentionPeriod.value); });
store.set(RICH_HISTORY_SETTING_KEYS.retentionPeriod, retentionPeriod.value);
}
}; };
toggleStarredTabAsFirstTab = () => { toggleStarredTabAsFirstTab = () => {

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui'; import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui';
@ -20,17 +20,31 @@ import { changeDatasource } from '../state/datasource';
import { setQueries } from '../state/query'; import { setQueries } from '../state/query';
import { ShowConfirmModalEvent } from '../../../types/events'; 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; query: RichHistoryQuery;
dsImg: string; dsImg: string;
isRemoved: boolean; isRemoved: boolean;
changeDatasource: typeof changeDatasource;
updateRichHistory: typeof updateRichHistory;
setQueries: typeof setQueries;
exploreId: ExploreId;
datasourceInstance: DataSourceApi;
} }
export type Props = ConnectedProps<typeof connector> & OwnProps;
const getStyles = stylesFactory((theme: GrafanaTheme, isRemoved: boolean) => { const getStyles = stylesFactory((theme: GrafanaTheme, isRemoved: boolean) => {
/* Hard-coded value so all buttons and icons on right side of card are aligned */ /* Hard-coded value so all buttons and icons on right side of card are aligned */
const rigtColumnWidth = '240px'; const rigtColumnWidth = '240px';
@ -304,19 +318,4 @@ export function RichHistoryCard(props: Props) {
); );
} }
function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { export default hot(module)(connector(RichHistoryCard));
const explore = state.explore;
const { datasourceInstance } = explore[exploreId]!;
return {
exploreId,
datasourceInstance,
};
}
const mapDispatchToProps = {
changeDatasource,
updateRichHistory,
setQueries,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(RichHistoryCard));

@ -1,6 +1,6 @@
// Libraries // Libraries
import React, { useState } from 'react'; import React, { useState } from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
// Services & Utils // Services & Utils
@ -9,7 +9,7 @@ import { RICH_HISTORY_SETTING_KEYS } from 'app/core/utils/richHistory';
// Types // Types
import { ExploreItemState, StoreState } from 'app/types'; import { ExploreItemState, StoreState } from 'app/types';
import { ExploreId, RichHistoryQuery } from 'app/types/explore'; import { ExploreId } from 'app/types/explore';
// Components, enums // Components, enums
import { RichHistory, Tabs } from './RichHistory'; import { RichHistory, Tabs } from './RichHistory';
@ -18,15 +18,34 @@ import { RichHistory, Tabs } from './RichHistory';
import { deleteRichHistory } from '../state/history'; import { deleteRichHistory } from '../state/history';
import { ExploreDrawer } from '../ExploreDrawer'; 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; width: number;
exploreId: ExploreId; exploreId: ExploreId;
activeDatasourceInstance: string;
richHistory: RichHistoryQuery[];
firstTab: Tabs;
deleteRichHistory: typeof deleteRichHistory;
onClose: () => void; onClose: () => void;
} }
export type Props = ConnectedProps<typeof connector> & OwnProps;
export function RichHistoryContainer(props: Props) { export function RichHistoryContainer(props: Props) {
const [height, setHeight] = useState(400); const [height, setHeight] = useState(400);
@ -53,24 +72,4 @@ export function RichHistoryContainer(props: Props) {
); );
} }
function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { export default hot(module)(connector(RichHistoryContainer));
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));

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { stylesFactory, useTheme, Select, Button, Switch, Field } from '@grafana/ui'; 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 appEvents from 'app/core/app_events';
import { ShowConfirmModalEvent } from '../../../types/events'; import { ShowConfirmModalEvent } from '../../../types/events';
import { dispatch } from 'app/store/store'; import { dispatch } from 'app/store/store';
@ -12,7 +12,7 @@ export interface RichHistorySettingsProps {
retentionPeriod: number; retentionPeriod: number;
starredTabAsFirstTab: boolean; starredTabAsFirstTab: boolean;
activeDatasourceOnly: boolean; activeDatasourceOnly: boolean;
onChangeRetentionPeriod: (option: { label: string; value: number }) => void; onChangeRetentionPeriod: (option: SelectableValue<number>) => void;
toggleStarredTabAsFirstTab: () => void; toggleStarredTabAsFirstTab: () => void;
toggleactiveDatasourceOnly: () => void; toggleactiveDatasourceOnly: () => void;
deleteRichHistory: () => void; deleteRichHistory: () => void;

@ -1,6 +1,5 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { NavModel } from '@grafana/data';
import { Button, Input, Form, Field } from '@grafana/ui'; import { Button, Input, Form, Field } from '@grafana/ui';
import Page from 'app/core/components/Page/Page'; import Page from 'app/core/components/Page/Page';
import { createNewFolder } from '../state/actions'; import { createNewFolder } from '../state/actions';
@ -8,15 +7,17 @@ import { getNavModel } from 'app/core/selectors/navModel';
import { StoreState } from 'app/types'; import { StoreState } from 'app/types';
import validationSrv from '../../manage-dashboards/services/ValidationSrv'; import validationSrv from '../../manage-dashboards/services/ValidationSrv';
interface OwnProps {} const mapStateToProps = (state: StoreState) => ({
navModel: getNavModel(state.navIndex, 'manage-dashboards'),
});
interface ConnectedProps { const mapDispatchToProps = {
navModel: NavModel; createNewFolder,
} };
interface DispatchProps { const connector = connect(mapStateToProps, mapDispatchToProps);
createNewFolder: typeof createNewFolder;
} interface OwnProps {}
interface FormModel { interface FormModel {
folderName: string; folderName: string;
@ -24,7 +25,7 @@ interface FormModel {
const initialFormModel: FormModel = { folderName: '' }; const initialFormModel: FormModel = { folderName: '' };
type Props = OwnProps & ConnectedProps & DispatchProps; type Props = OwnProps & ConnectedProps<typeof connector>;
export class NewDashboardsFolder extends PureComponent<Props> { export class NewDashboardsFolder extends PureComponent<Props> {
onSubmit = (formData: FormModel) => { onSubmit = (formData: FormModel) => {
@ -72,12 +73,4 @@ export class NewDashboardsFolder extends PureComponent<Props> {
} }
} }
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (state) => ({ export default connector(NewDashboardsFolder);
navModel: getNavModel(state.navIndex, 'manage-dashboards'),
});
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
createNewFolder,
};
export default connect(mapStateToProps, mapDispatchToProps)(NewDashboardsFolder);

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { LegacyForms, DeleteButton } from '@grafana/ui'; import { LegacyForms, DeleteButton } from '@grafana/ui';
const { Select } = LegacyForms; const { Select } = LegacyForms;
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
@ -9,14 +9,20 @@ import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
import { updateTeamMember, removeTeamMember } from './state/actions'; import { updateTeamMember, removeTeamMember } from './state/actions';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
export interface Props { const mapDispatchToProps = {
removeTeamMember,
updateTeamMember,
};
const connector = connect(null, mapDispatchToProps);
interface OwnProps {
member: TeamMember; member: TeamMember;
syncEnabled: boolean; syncEnabled: boolean;
editorsCanAdmin: boolean; editorsCanAdmin: boolean;
signedInUserIsTeamAdmin: boolean; signedInUserIsTeamAdmin: boolean;
removeTeamMember: typeof removeTeamMember;
updateTeamMember: typeof updateTeamMember;
} }
export type Props = ConnectedProps<typeof connector> & OwnProps;
export class TeamMemberRow extends PureComponent<Props> { export class TeamMemberRow extends PureComponent<Props> {
constructor(props: Props) { constructor(props: Props) {
@ -97,13 +103,4 @@ export class TeamMemberRow extends PureComponent<Props> {
} }
} }
function mapStateToProps(state: any) { export default connector(TeamMemberRow);
return {};
}
const mapDispatchToProps = {
removeTeamMember,
updateTeamMember,
};
export default connect(mapStateToProps, mapDispatchToProps)(TeamMemberRow);

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react'; 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 { SlideDown } from 'app/core/components/Animations/SlideDown';
import { UserPicker } from 'app/core/components/Select/UserPicker'; import { UserPicker } from 'app/core/components/Select/UserPicker';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; 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 { FilterInput } from 'app/core/components/FilterInput/FilterInput';
import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
import { config } from 'app/core/config'; 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 TeamMemberRow from './TeamMemberRow';
import { setSearchMemberQuery } from './state/reducers'; import { setSearchMemberQuery } from './state/reducers';
import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
import { Button } from '@grafana/ui'; import { Button } from '@grafana/ui';
import { SelectableValue } from '@grafana/data'; 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[]; members: TeamMember[];
searchMemberQuery: string;
addTeamMember: typeof addTeamMember;
setSearchMemberQuery: typeof setSearchMemberQuery;
syncEnabled: boolean; syncEnabled: boolean;
editorsCanAdmin: boolean;
signedInUser: SignedInUser;
} }
export type Props = ConnectedProps<typeof connector> & OwnProps;
export interface State { export interface State {
isAdding: boolean; isAdding: boolean;
newTeamMember?: SelectableValue<OrgUser['userId']> | null; newTeamMember?: SelectableValue<OrgUser['userId']> | null;
@ -133,17 +145,4 @@ export class TeamMembers extends PureComponent<Props, State> {
} }
} }
function mapStateToProps(state: any) { export default connector(TeamMembers);
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);

@ -1,15 +1,21 @@
import React, { FC } from 'react'; 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 { Input, Field, Form, Button, FieldSet, VerticalGroup } from '@grafana/ui';
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
import { updateTeam } from './state/actions'; import { updateTeam } from './state/actions';
import { Team } from 'app/types'; import { Team } from 'app/types';
export interface Props { const mapDispatchToProps = {
updateTeam,
};
const connector = connect(null, mapDispatchToProps);
interface OwnProps {
team: Team; team: Team;
updateTeam: typeof updateTeam;
} }
export type Props = ConnectedProps<typeof connector> & OwnProps;
export const TeamSettings: FC<Props> = ({ team, updateTeam }) => { export const TeamSettings: FC<Props> = ({ team, updateTeam }) => {
return ( return (
@ -43,8 +49,4 @@ export const TeamSettings: FC<Props> = ({ team, updateTeam }) => {
); );
}; };
const mapDispatchToProps = { export default connector(TeamSettings);
updateTeam,
};
export default connect(null, mapDispatchToProps)(TeamSettings);

@ -32,7 +32,7 @@ export const MetricPicker = ({ options, onChange, className, value }: Props) =>
options={toOptions(options)} options={toOptions(options)}
onChange={onChange} onChange={onChange}
placeholder="Select Metric" placeholder="Select Metric"
value={!!selectedOption ? toOption(selectedOption) : null} value={!!selectedOption ? toOption(selectedOption) : undefined}
/> />
); );
}; };

@ -94,7 +94,7 @@ describe('Metric Editor', () => {
const getFields: ElasticDatasource['getFields'] = jest.fn(() => from([[]])); const getFields: ElasticDatasource['getFields'] = jest.fn(() => from([[]]));
const wrapper = ({ children }: { children: ReactNode }) => ( const wrapper = ({ children }: { children?: ReactNode }) => (
<ElasticsearchProvider <ElasticsearchProvider
datasource={{ getFields, esVersion, xpack } as ElasticDatasource} datasource={{ getFields, esVersion, xpack } as ElasticDatasource}
query={query} query={query}

@ -2,6 +2,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { LokiQuery } from '../types'; import { LokiQuery } from '../types';
import { SelectableValue } from '@grafana/data';
// Types // Types
import { InlineFormLabel, RadioButtonGroup, InlineField, Input } from '@grafana/ui'; import { InlineFormLabel, RadioButtonGroup, InlineField, Input } from '@grafana/ui';
@ -17,7 +18,7 @@ export interface LokiOptionFieldsProps {
type LokiQueryType = 'instant' | 'range'; type LokiQueryType = 'instant' | 'range';
const queryTypeOptions = [ const queryTypeOptions: Array<SelectableValue<LokiQueryType>> = [
{ value: 'range', label: 'Range', description: 'Run query over a range of time.' }, { value: 'range', label: 'Range', description: 'Run query over a range of time.' },
{ {
value: 'instant', value: 'instant',

@ -58,31 +58,37 @@ export const ScaleDimensionEditor: FC<StandardEditorProps<ScaleDimensionConfig,
); );
const onMinChange = useCallback( const onMinChange = useCallback(
(min: number) => { (min?: number) => {
validateAndDoChange({ if (min !== undefined) {
...value, validateAndDoChange({
min, ...value,
}); min,
});
}
}, },
[validateAndDoChange, value] [validateAndDoChange, value]
); );
const onMaxChange = useCallback( const onMaxChange = useCallback(
(max: number) => { (max?: number) => {
validateAndDoChange({ if (max !== undefined) {
...value, validateAndDoChange({
max, ...value,
}); max,
});
}
}, },
[validateAndDoChange, value] [validateAndDoChange, value]
); );
const onValueChange = useCallback( const onValueChange = useCallback(
(fixed: number) => { (fixed?: number) => {
validateAndDoChange({ if (fixed !== undefined) {
...value, validateAndDoChange({
fixed, ...value,
}); fixed,
});
}
}, },
[validateAndDoChange, value] [validateAndDoChange, value]
); );

@ -147,7 +147,7 @@ export const ContextMenuPlugin: React.FC<ContextMenuPluginProps> = ({
items: i.items.map((j) => { items: i.items.map((j) => {
return { return {
...j, ...j,
onClick: (e: React.SyntheticEvent<HTMLElement>) => { onClick: (e?: React.SyntheticEvent<HTMLElement>) => {
if (!coords) { if (!coords) {
return; return;
} }

@ -3,7 +3,7 @@ set -e
echo -e "Collecting code stats (typescript errors & more)" 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+)')" 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 if [ "$ERROR_COUNT" -gt $ERROR_COUNT_LIMIT ]; then

Loading…
Cancel
Save