mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Update and enforce usage of typed react-redux hooks (#55349)
* Chore: Update and enforce usage of typed react-redux hooks
This commit is contained in:
parent
a3ff758874
commit
64bbb7a7ce
12
.eslintrc
12
.eslintrc
@ -19,6 +19,18 @@
|
||||
"alphabetize": { "order": "asc" }
|
||||
}
|
||||
],
|
||||
"no-restricted-imports": [
|
||||
"warn",
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "react-redux",
|
||||
"importNames": ["useDispatch", "useSelector"],
|
||||
"message": "Please import from app/types instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// Use typescript's no-redeclare for compatibility with overrides
|
||||
"no-redeclare": "off",
|
||||
|
@ -21,9 +21,14 @@ export interface ExploreTracePanelState {
|
||||
spanId?: string;
|
||||
}
|
||||
|
||||
export interface SplitOpenOptions<T> {
|
||||
datasourceUid: string;
|
||||
query: T;
|
||||
range?: TimeRange;
|
||||
panelsState?: ExplorePanelsState;
|
||||
}
|
||||
|
||||
/**
|
||||
* SplitOpen type is used in Explore and related components.
|
||||
*/
|
||||
export type SplitOpen = <T extends DataQuery = any>(
|
||||
options?: { datasourceUid: string; query: T; range?: TimeRange; panelsState?: ExplorePanelsState } | undefined
|
||||
) => void;
|
||||
export type SplitOpen = <T extends DataQuery = any>(options?: SplitOpenOptions<T> | undefined) => void;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, NavSection } from '@grafana/data';
|
||||
@ -9,7 +8,7 @@ import { locationService } from '@grafana/runtime';
|
||||
import { Dropdown, FilterInput, Icon, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { useSearchQuery } from 'app/features/search/hooks/useSearchQuery';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { enrichConfigItems, enrichWithInteractionTracking } from '../NavBar/utils';
|
||||
import { OrgSwitcher } from '../OrgSwitcher';
|
||||
@ -21,7 +20,7 @@ export function TopSearchBar() {
|
||||
const styles = useStyles2(getStyles);
|
||||
const location = useLocation();
|
||||
const { query, onQueryChange } = useSearchQuery({});
|
||||
const navBarTree = useSelector((state: StoreState) => state.navBarTree);
|
||||
const navBarTree = useSelector((state) => state.navBarTree);
|
||||
const navTree = cloneDeep(navBarTree);
|
||||
const [showSwitcherModal, setShowSwitcherModal] = useState(false);
|
||||
const toggleSwitcherModal = () => {
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { useTheme2 } from '@grafana/ui';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { enrichConfigItems, enrichWithInteractionTracking, getActiveItem } from '../NavBar/utils';
|
||||
|
||||
@ -19,7 +18,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export const MegaMenu = React.memo<Props>(({ onClose, searchBarHidden }) => {
|
||||
const navBarTree = useSelector((state: StoreState) => state.navBarTree);
|
||||
const navBarTree = useSelector((state) => state.navBarTree);
|
||||
const theme = useTheme2();
|
||||
const styles = getStyles(theme);
|
||||
const location = useLocation();
|
||||
|
@ -3,14 +3,13 @@ import { FocusScope } from '@react-aria/focus';
|
||||
import { Location as HistoryLocation } from 'history';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data';
|
||||
import { config, locationSearchToObject, locationService, reportInteraction } from '@grafana/runtime';
|
||||
import { Icon, useTheme2, CustomScrollbar } from '@grafana/ui';
|
||||
import { getKioskMode } from 'app/core/navigation/kiosk';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { OrgSwitcher } from '../OrgSwitcher';
|
||||
|
||||
@ -35,7 +34,7 @@ const onOpenSearch = () => {
|
||||
};
|
||||
|
||||
export const NavBar = React.memo(() => {
|
||||
const navBarTree = useSelector((state: StoreState) => state.navBarTree);
|
||||
const navBarTree = useSelector((state) => state.navBarTree);
|
||||
const theme = useTheme2();
|
||||
const styles = getStyles(theme);
|
||||
const location = useLocation();
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { store } from 'app/store/store';
|
||||
import { StoreState } from 'app/types';
|
||||
import { StoreState, useSelector } from 'app/types';
|
||||
|
||||
export function usePageNav(navId?: string, oldProp?: NavModel): NavModel | undefined {
|
||||
if (oldProp) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import hoistNonReactStatics from 'hoist-non-react-statics';
|
||||
import React, { ComponentType, FunctionComponent, useEffect } from 'react';
|
||||
import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux';
|
||||
import { connect, MapDispatchToPropsParam, MapStateToPropsParam } from 'react-redux';
|
||||
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { cleanUpAction, CleanUpAction } from '../actions/cleanUp';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { cleanUpAction, CleanUpAction } from '../actions/cleanUp';
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { StoreState } from 'app/types/store';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { getNavModel } from '../selectors/navModel';
|
||||
|
||||
export const useNavModel = (id: string): NavModel => {
|
||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
return getNavModel(navIndex, id);
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
|
||||
import { NoAlertManagerWarning } from './components/NoAlertManagerWarning';
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { isEqual, orderBy, uniqWith } from 'lodash';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useDebounce } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Card, FilterInput, Icon, Pagination, Select, Stack, TagList, useStyles2 } from '@grafana/ui';
|
||||
import { DEFAULT_PER_PAGE_PAGINATION } from 'app/core/constants';
|
||||
import { getQueryParamValue } from 'app/core/utils/query';
|
||||
import { FolderState } from 'app/types';
|
||||
import { FolderState, useDispatch } from 'app/types';
|
||||
import { CombinedRule } from 'app/types/unified-alerting';
|
||||
|
||||
import { useCombinedRuleNamespaces } from './hooks/useCombinedRuleNamespaces';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui';
|
||||
import { Receiver } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useCleanup } from '../../../core/hooks/useCleanup';
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Route, Redirect, Switch } from 'react-router-dom';
|
||||
|
||||
import { Alert, LoadingPlaceholder } from '@grafana/ui';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import MuteTimingForm from './components/amroutes/MuteTimingForm';
|
||||
import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Redirect, Route, RouteChildrenProps, Switch, useLocation, useParams } from 'react-router-dom';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { AlertManagerPicker } from './components/AlertManagerPicker';
|
||||
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
@ -8,6 +7,7 @@ import { Alert, LinkButton, LoadingPlaceholder, useStyles2, withErrorBoundary }
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { RuleIdentifier } from 'app/types/unified-alerting';
|
||||
|
||||
import { AlertRuleForm } from './components/rule-editor/AlertRuleForm';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, urlUtil } from '@grafana/data';
|
||||
import { Button, LinkButton, useStyles2, withErrorBoundary } from '@grafana/ui';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
|
||||
import { NoRulesSplash } from './components/rules/NoRulesCTA';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { FC, useCallback, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Redirect, Route, RouteChildrenProps, Switch, useLocation } from 'react-router-dom';
|
||||
|
||||
import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui';
|
||||
import { Silence } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { featureDiscoveryApi } from './api/featureDiscoveryApi';
|
||||
import { AlertManagerPicker } from './components/AlertManagerPicker';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect, useState, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, Button, ConfirmModal, TextArea, HorizontalGroup, Field, Form, useStyles2 } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName';
|
||||
import { useAlertManagersByPermission } from '../../hooks/useAlertManagerSources';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import {
|
||||
@ -18,6 +17,7 @@ import {
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { loadDataSources } from 'app/features/datasources/state/actions';
|
||||
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
import { StoreState } from 'app/types/store';
|
||||
|
||||
import { useExternalAmSelector, useExternalDataSourceAlertmanagers } from '../../hooks/useExternalAmSelector';
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useMemo } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, Field, FieldSet, Input, Button, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
@ -10,6 +9,7 @@ import {
|
||||
AlertManagerCortexConfig,
|
||||
MuteTimeInterval,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName';
|
||||
import { useAlertManagersByPermission } from '../../hooks/useAlertManagerSources';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { IconButton, LinkButton, Link, useStyles2, ConfirmModal } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AlertManagerCortexConfig, MuteTimeInterval, TimeInterval } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { Authorize } from '../../components/Authorize';
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
|
@ -1,12 +1,11 @@
|
||||
import React, { FC } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { urlUtil } from '@grafana/data';
|
||||
import { Alert, Button, LinkButton } from '@grafana/ui';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { panelToRuleFormValues } from '../../utils/rule-form';
|
||||
|
||||
@ -17,7 +16,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export const NewRuleFromPanelButton: FC<Props> = ({ dashboard, panel, className }) => {
|
||||
const templating = useSelector((state: StoreState) => {
|
||||
const templating = useSelector((state) => {
|
||||
return state.templating;
|
||||
});
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { FC } from 'react';
|
||||
import { useForm, FormProvider } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { Alert, Button, HorizontalGroup, LinkButton } from '@grafana/ui';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
import { updateAlertManagerConfigAction } from '../../state/actions';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Button, ConfirmModal, Modal, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { Authorize } from '../../components/Authorize';
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC } from 'react';
|
||||
import { useForm, Validate } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, Button, Field, FieldSet, Input, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
import { updateAlertManagerConfigAction } from '../../state/actions';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { FC, Fragment, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { ConfirmModal, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { Authorize } from '../../components/Authorize';
|
||||
import { deleteTemplateAction } from '../../state/actions';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { FC, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { updateAlertManagerConfigAction } from '../../../state/actions';
|
||||
import { CloudChannelValues, ReceiverFormValues, CloudChannelMap } from '../../../types/receiver-form';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React, { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { LoadingPlaceholder } from '@grafana/ui';
|
||||
import {
|
||||
@ -8,6 +7,7 @@ import {
|
||||
Receiver,
|
||||
TestReceiversAlert,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector';
|
||||
import {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import { FormProvider, useForm, UseFormWatch } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
@ -9,6 +8,7 @@ import { Button, ConfirmModal, CustomScrollbar, PageToolbar, Spinner, useStyles2
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { RuleWithLocation } from 'app/types/unified-alerting';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Field, InputControl, useStyles2 } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
import { fetchRulerRulesAction } from '../../state/actions';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { isValidGoDuration } from '@grafana/data';
|
||||
import { Modal, Button, Form, Field, Input, useStyles2 } from '@grafana/ui';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting';
|
||||
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, Fragment, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, urlUtil } from '@grafana/data';
|
||||
@ -8,7 +7,7 @@ import { config } from '@grafana/runtime';
|
||||
import { Button, ClipboardButton, ConfirmModal, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
import { AccessControlAction, useDispatch } from 'app/types';
|
||||
import { CombinedRule, RulesSource } from 'app/types/unified-alerting';
|
||||
|
||||
import { useIsRuleEditable } from '../../hooks/useIsRuleEditable';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import pluralize from 'pluralize';
|
||||
import React, { FC, useEffect, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Badge, ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting';
|
||||
|
||||
import { useFolder } from '../../hooks/useFolder';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useDebounce } from 'react-use';
|
||||
|
||||
import { dateTime, GrafanaTheme2 } from '@grafana/data';
|
||||
import { Badge, useStyles2 } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { Alert, AlertingRule } from 'app/types/unified-alerting';
|
||||
|
||||
import { useCombinedRuleNamespaces } from '../../hooks/useCombinedRuleNamespaces';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React, { FC, Fragment, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { dateMath, GrafanaTheme, intervalToAbbreviatedDurationString } from '@grafana/data';
|
||||
import { useStyles, Link } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { Silence, AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { expireSilenceAction } from '../../state/actions';
|
||||
import { makeAMLink } from '../../utils/misc';
|
||||
|
@ -2,7 +2,6 @@ import { css, cx } from '@emotion/css';
|
||||
import { pickBy } from 'lodash';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import { useForm, FormProvider } from 'react-hook-form';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useDebounce } from 'react-use';
|
||||
|
||||
import {
|
||||
@ -18,6 +17,7 @@ import { config } from '@grafana/runtime';
|
||||
import { Button, Field, FieldSet, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { MatcherOperator, Silence, SilenceCreatePayload } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useURLSearchParams } from '../../hooks/useURLSearchParams';
|
||||
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, dateMath } from '@grafana/data';
|
||||
import { Icon, useStyles2, Link, Button, Stack } from '@grafana/ui';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AlertmanagerAlert, Silence, SilenceState } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { expireSilenceAction } from '../../state/actions';
|
||||
import { getInstancesPermissions } from '../../utils/access-control';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { useDispatch } from 'app/types';
|
||||
import { CombinedRule, RuleIdentifier, RuleNamespace } from 'app/types/unified-alerting';
|
||||
import { RulerRulesConfigDTO } from 'app/types/unified-alerting-dto';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import React from 'react';
|
||||
import * as reactRedux from 'react-redux';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { DataSourceJsonData, DataSourceSettings } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
@ -10,17 +10,12 @@ import { mockDataSource, mockDataSourcesStore, mockStore } from '../mocks';
|
||||
|
||||
import { useExternalAmSelector, useExternalDataSourceAlertmanagers } from './useExternalAmSelector';
|
||||
|
||||
const useSelectorMock = jest.spyOn(reactRedux, 'useSelector');
|
||||
|
||||
describe('useExternalAmSelector', () => {
|
||||
beforeEach(() => {
|
||||
useSelectorMock.mockClear();
|
||||
});
|
||||
it('should have one in pending', () => {
|
||||
useSelectorMock.mockImplementation((callback) => {
|
||||
return callback(createMockStoreState([], [], ['some/url/to/am']));
|
||||
});
|
||||
const alertmanagers = useExternalAmSelector();
|
||||
const store = createMockStoreState([], [], ['some/url/to/am']);
|
||||
const wrapper = ({ children }: React.PropsWithChildren<{}>) => <Provider store={store}>{children}</Provider>;
|
||||
const { result } = renderHook(() => useExternalAmSelector(), { wrapper });
|
||||
const alertmanagers = result.current;
|
||||
|
||||
expect(alertmanagers).toEqual([
|
||||
{
|
||||
@ -32,13 +27,14 @@ describe('useExternalAmSelector', () => {
|
||||
});
|
||||
|
||||
it('should have one active, one pending', () => {
|
||||
useSelectorMock.mockImplementation((callback) => {
|
||||
return callback(
|
||||
createMockStoreState([{ url: 'some/url/to/am/api/v2/alerts' }], [], ['some/url/to/am', 'some/url/to/am1'])
|
||||
);
|
||||
});
|
||||
|
||||
const alertmanagers = useExternalAmSelector();
|
||||
const store = createMockStoreState(
|
||||
[{ url: 'some/url/to/am/api/v2/alerts' }],
|
||||
[],
|
||||
['some/url/to/am', 'some/url/to/am1']
|
||||
);
|
||||
const wrapper = ({ children }: React.PropsWithChildren<{}>) => <Provider store={store}>{children}</Provider>;
|
||||
const { result } = renderHook(() => useExternalAmSelector(), { wrapper });
|
||||
const alertmanagers = result.current;
|
||||
|
||||
expect(alertmanagers).toEqual([
|
||||
{
|
||||
@ -55,17 +51,14 @@ describe('useExternalAmSelector', () => {
|
||||
});
|
||||
|
||||
it('should have two active', () => {
|
||||
useSelectorMock.mockImplementation((callback) => {
|
||||
return callback(
|
||||
createMockStoreState(
|
||||
[{ url: 'some/url/to/am/api/v2/alerts' }, { url: 'some/url/to/am1/api/v2/alerts' }],
|
||||
[],
|
||||
['some/url/to/am', 'some/url/to/am1']
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
const alertmanagers = useExternalAmSelector();
|
||||
const store = createMockStoreState(
|
||||
[{ url: 'some/url/to/am/api/v2/alerts' }, { url: 'some/url/to/am1/api/v2/alerts' }],
|
||||
[],
|
||||
['some/url/to/am', 'some/url/to/am1']
|
||||
);
|
||||
const wrapper = ({ children }: React.PropsWithChildren<{}>) => <Provider store={store}>{children}</Provider>;
|
||||
const { result } = renderHook(() => useExternalAmSelector(), { wrapper });
|
||||
const alertmanagers = result.current;
|
||||
|
||||
expect(alertmanagers).toEqual([
|
||||
{
|
||||
@ -82,18 +75,15 @@ describe('useExternalAmSelector', () => {
|
||||
});
|
||||
|
||||
it('should have one active, one dropped, one pending', () => {
|
||||
useSelectorMock.mockImplementation((callback) => {
|
||||
return callback(
|
||||
createMockStoreState(
|
||||
[{ url: 'some/url/to/am/api/v2/alerts' }],
|
||||
[{ url: 'some/dropped/url/api/v2/alerts' }],
|
||||
['some/url/to/am', 'some/url/to/am1']
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
const alertmanagers = useExternalAmSelector();
|
||||
const store = createMockStoreState(
|
||||
[{ url: 'some/url/to/am/api/v2/alerts' }],
|
||||
[{ url: 'some/dropped/url/api/v2/alerts' }],
|
||||
['some/url/to/am', 'some/url/to/am1']
|
||||
);
|
||||
const wrapper = ({ children }: React.PropsWithChildren<{}>) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
const { result } = renderHook(() => useExternalAmSelector(), { wrapper });
|
||||
const alertmanagers = result.current;
|
||||
expect(alertmanagers).toEqual([
|
||||
{
|
||||
url: 'some/url/to/am',
|
||||
@ -114,21 +104,19 @@ describe('useExternalAmSelector', () => {
|
||||
});
|
||||
|
||||
it('The number of alert managers should match config entries when there are multiple entries of the same url', () => {
|
||||
useSelectorMock.mockImplementation((callback) => {
|
||||
return callback(
|
||||
createMockStoreState(
|
||||
[
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
],
|
||||
[],
|
||||
['same/url/to/am', 'same/url/to/am', 'same/url/to/am']
|
||||
)
|
||||
);
|
||||
});
|
||||
const store = createMockStoreState(
|
||||
[
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
{ url: 'same/url/to/am/api/v2/alerts' },
|
||||
],
|
||||
[],
|
||||
['same/url/to/am', 'same/url/to/am', 'same/url/to/am']
|
||||
);
|
||||
const wrapper = ({ children }: React.PropsWithChildren<{}>) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
const alertmanagers = useExternalAmSelector();
|
||||
const { result } = renderHook(() => useExternalAmSelector(), { wrapper });
|
||||
const alertmanagers = result.current;
|
||||
|
||||
expect(alertmanagers.length).toBe(3);
|
||||
expect(alertmanagers).toEqual([
|
||||
@ -152,10 +140,6 @@ describe('useExternalAmSelector', () => {
|
||||
});
|
||||
|
||||
describe('useExternalDataSourceAlertmanagers', () => {
|
||||
beforeEach(() => {
|
||||
useSelectorMock.mockRestore();
|
||||
});
|
||||
|
||||
it('Should merge data sources information from config and api responses', () => {
|
||||
// Arrange
|
||||
const { dsSettings, dsInstanceSettings } = setupAlertmanagerDataSource({ url: 'http://grafana.com' });
|
||||
@ -168,7 +152,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
dataSources: [dsSettings],
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -199,7 +183,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -230,7 +214,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -261,7 +245,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -292,7 +276,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -326,7 +310,7 @@ describe('useExternalDataSourceAlertmanagers', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const wrapper: React.FC = ({ children }) => <reactRedux.Provider store={store}>{children}</reactRedux.Provider>;
|
||||
const wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider>;
|
||||
|
||||
// Act
|
||||
const {
|
||||
@ -389,28 +373,16 @@ const createMockStoreState = (
|
||||
droppedAlertmanagers: Array<{ url: string }>,
|
||||
alertmanagerConfig: string[]
|
||||
) => {
|
||||
return {
|
||||
unifiedAlerting: {
|
||||
externalAlertmanagers: {
|
||||
discoveredAlertmanagers: {
|
||||
result: {
|
||||
data: {
|
||||
activeAlertManagers: activeAlertmanagers,
|
||||
droppedAlertManagers: droppedAlertmanagers,
|
||||
},
|
||||
},
|
||||
dispatched: false,
|
||||
loading: false,
|
||||
},
|
||||
alertmanagerConfig: {
|
||||
result: {
|
||||
alertmanagers: alertmanagerConfig,
|
||||
alertmanagersChoice: AlertmanagerChoice.All,
|
||||
},
|
||||
dispatched: false,
|
||||
loading: false,
|
||||
},
|
||||
return mockStore((state) => {
|
||||
state.unifiedAlerting.externalAlertmanagers.alertmanagerConfig.result = {
|
||||
alertmanagers: alertmanagerConfig,
|
||||
alertmanagersChoice: AlertmanagerChoice.All,
|
||||
};
|
||||
state.unifiedAlerting.externalAlertmanagers.discoveredAlertmanagers.result = {
|
||||
data: {
|
||||
activeAlertManagers: activeAlertmanagers,
|
||||
droppedAlertManagers: droppedAlertmanagers,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { countBy, keyBy } from 'lodash';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { DataSourceInstanceSettings, DataSourceJsonData, DataSourceSettings } from '@grafana/data';
|
||||
import { AlertManagerDataSourceJsonData } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { StoreState } from '../../../../types';
|
||||
import { getAlertManagerDataSources } from '../utils/datasource';
|
||||
|
||||
import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';
|
||||
@ -14,10 +13,10 @@ type AlertmanagerConfig = { url: string; status: string; actualUrl: string };
|
||||
|
||||
export function useExternalAmSelector(): AlertmanagerConfig[] | [] {
|
||||
const discoveredAlertmanagers = useSelector(
|
||||
(state: StoreState) => state.unifiedAlerting.externalAlertmanagers.discoveredAlertmanagers.result?.data
|
||||
(state) => state.unifiedAlerting.externalAlertmanagers.discoveredAlertmanagers.result?.data
|
||||
);
|
||||
const alertmanagerConfig = useSelector(
|
||||
(state: StoreState) => state.unifiedAlerting.externalAlertmanagers.alertmanagerConfig.result?.alertmanagers
|
||||
(state) => state.unifiedAlerting.externalAlertmanagers.alertmanagerConfig.result?.alertmanagers
|
||||
);
|
||||
|
||||
if (!discoveredAlertmanagers || !alertmanagerConfig) {
|
||||
@ -69,7 +68,7 @@ export interface ExternalDataSourceAM {
|
||||
export function useExternalDataSourceAlertmanagers(): ExternalDataSourceAM[] {
|
||||
const externalDsAlertManagers = getAlertManagerDataSources().filter((ds) => ds.jsonData.handleGrafanaManagedAlerts);
|
||||
|
||||
const alertmanagerDatasources = useSelector((state: StoreState) =>
|
||||
const alertmanagerDatasources = useSelector((state) =>
|
||||
keyBy(
|
||||
state.dataSources.dataSources.filter((ds) => ds.type === 'alertmanager'),
|
||||
(ds) => ds.uid
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { FolderDTO } from 'app/types';
|
||||
import { FolderDTO, useDispatch } from 'app/types';
|
||||
|
||||
import { fetchFolderIfNotFetchedAction } from '../state/actions';
|
||||
import { initialAsyncRequestState } from '../utils/redux';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { useDispatch } from 'app/types';
|
||||
import { StateHistoryItem } from 'app/types/unified-alerting';
|
||||
|
||||
import { fetchGrafanaAnnotationsAction } from '../state/actions';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { SerializedError } from '@reduxjs/toolkit';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { CombinedRule } from 'app/types/unified-alerting';
|
||||
|
||||
import { fetchPromRulesAction, fetchRulerRulesAction } from '../state/actions';
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { UnifiedAlertingState } from '../state/reducers';
|
||||
|
||||
@ -8,5 +6,5 @@ export function useUnifiedAlertingSelector<TSelected = unknown>(
|
||||
selector: (state: UnifiedAlertingState) => TSelected,
|
||||
equalityFn?: (left: TSelected, right: TSelected) => boolean
|
||||
): TSelected {
|
||||
return useSelector((state: StoreState) => selector(state.unifiedAlerting), equalityFn);
|
||||
return useSelector((state) => selector(state.unifiedAlerting), equalityFn);
|
||||
}
|
||||
|
@ -13,13 +13,12 @@ import {
|
||||
useKBar,
|
||||
} from 'kbar';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { reportInteraction, locationService } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { ResultItem } from './ResultItem';
|
||||
import getDashboardNavActions from './actions/dashboard.nav.actions';
|
||||
@ -40,7 +39,7 @@ export const CommandPalette = () => {
|
||||
}));
|
||||
const isNotLogin = locationService.getLocation().pathname !== '/login';
|
||||
|
||||
const { navBarTree } = useSelector((state: StoreState) => {
|
||||
const { navBarTree } = useSelector((state) => {
|
||||
return {
|
||||
navBarTree: state.navBarTree,
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import * as H from 'history';
|
||||
import { each, find } from 'lodash';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Prompt } from 'react-router-dom';
|
||||
|
||||
import { locationService } from '@grafana/runtime';
|
||||
@ -10,6 +9,7 @@ import { appEvents } from 'app/core/app_events';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal';
|
||||
import { PanelModelWithLibraryPanel } from 'app/features/library-panels/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { DashboardSavedEvent } from 'app/types/events';
|
||||
|
||||
import { DashboardModel } from '../../state/DashboardModel';
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { OptionsPaneOptions } from './OptionsPaneOptions';
|
||||
import { VisualizationButton } from './VisualizationButton';
|
||||
@ -23,7 +22,7 @@ export const OptionsPane: React.FC<OptionPaneRenderProps> = ({
|
||||
instanceState,
|
||||
}) => {
|
||||
const styles = useStyles(getStyles);
|
||||
const isVizPickerOpen = useSelector((state: StoreState) => state.panelEditor.isVizPickerOpen);
|
||||
const isVizPickerOpen = useSelector((state) => state.panelEditor.isVizPickerOpen);
|
||||
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);
|
||||
|
||||
return (
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { ToolbarButton, ButtonGroup, useStyles } from '@grafana/ui';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { PanelModel } from '../../state';
|
||||
import { getPanelPluginWithFallback } from '../../state/selectors';
|
||||
@ -20,8 +19,8 @@ export const VisualizationButton: FC<Props> = ({ panel }) => {
|
||||
const styles = useStyles(getStyles);
|
||||
const dispatch = useDispatch();
|
||||
const plugin = useSelector(getPanelPluginWithFallback(panel.type));
|
||||
const isPanelOptionsVisible = useSelector((state: StoreState) => state.panelEditor.ui.isPanelOptionsVisible);
|
||||
const isVizPickerOpen = useSelector((state: StoreState) => state.panelEditor.isVizPickerOpen);
|
||||
const isPanelOptionsVisible = useSelector((state) => state.panelEditor.ui.isPanelOptionsVisible);
|
||||
const isVizPickerOpen = useSelector((state) => state.panelEditor.isVizPickerOpen);
|
||||
|
||||
const onToggleOpen = () => {
|
||||
dispatch(toggleVizPicker(!isVizPickerOpen));
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useCallback, useRef, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
|
||||
import { GrafanaTheme, PanelData, SelectableValue } from '@grafana/data';
|
||||
@ -11,6 +10,7 @@ import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants';
|
||||
import { PanelLibraryOptionsGroup } from 'app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup';
|
||||
import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions';
|
||||
import { VizTypeChangeDetails } from 'app/features/panel/components/VizTypePicker/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { VizTypePicker } from '../../../panel/components/VizTypePicker/VizTypePicker';
|
||||
import { changePanelPlugin } from '../../../panel/state/actions';
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React, { FC, useCallback, useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { StoreState } from '../../../../types';
|
||||
import { getLastKey, getVariablesByKey } from '../../../variables/state/selectors';
|
||||
|
||||
export interface Props {
|
||||
@ -14,7 +13,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export const RepeatRowSelect: FC<Props> = ({ repeat, onChange, id }) => {
|
||||
const variables = useSelector((state: StoreState) => {
|
||||
const variables = useSelector((state) => {
|
||||
return getVariablesByKey(getLastKey(state), state);
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
|
||||
import { locationUtil } from '@grafana/data';
|
||||
@ -10,6 +9,7 @@ import { contextSrv } from 'app/core/core';
|
||||
import { updateDashboardName } from 'app/core/reducers/navBarTree';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { saveDashboard as saveDashboardApiCall } from 'app/features/manage-dashboards/state/actions';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { DashboardSavedEvent } from 'app/types/events';
|
||||
|
||||
import { SaveDashboardOptions } from './types';
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useAsyncFn } from 'react-use';
|
||||
|
||||
import { locationUtil } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { DashboardModel } from '../../state';
|
||||
|
||||
@ -16,7 +15,7 @@ const restoreDashboard = async (version: number, dashboard: DashboardModel) => {
|
||||
};
|
||||
|
||||
export const useDashboardRestore = (version: number) => {
|
||||
const dashboard = useSelector((state: StoreState) => state.dashboard.getModel());
|
||||
const dashboard = useSelector((state) => state.dashboard.getModel());
|
||||
const [state, onRestoreDashboard] = useAsyncFn(async () => await restoreDashboard(version, dashboard!), []);
|
||||
const notifyApp = useAppNotification();
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { FC, ReactElement, useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { PanelMenuItem } from '@grafana/data';
|
||||
import { getPanelStateForModel } from 'app/features/panel/state/selectors';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { StoreState } from '../../../../types';
|
||||
import { DashboardModel, PanelModel } from '../../state';
|
||||
import { getPanelMenu } from '../../utils/getPanelMenu';
|
||||
|
||||
@ -20,7 +19,7 @@ interface Props {
|
||||
|
||||
export const PanelHeaderMenuProvider: FC<Props> = ({ panel, dashboard, children }) => {
|
||||
const [items, setItems] = useState<PanelMenuItem[]>([]);
|
||||
const angularComponent = useSelector((state: StoreState) => getPanelStateForModel(state, panel)?.angularComponent);
|
||||
const angularComponent = useSelector((state) => getPanelStateForModel(state, panel)?.angularComponent);
|
||||
|
||||
useEffect(() => {
|
||||
setItems(getPanelMenu(dashboard, panel, angularComponent));
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { StoreState } from 'app/types/store';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { ROUTE_BASE_ID } from '../constants';
|
||||
|
||||
@ -11,7 +10,7 @@ import { ROUTE_BASE_ID } from '../constants';
|
||||
// the child nav-model-item's ID on the call-site.)
|
||||
export const useNavModel = () => {
|
||||
const { pathname: currentPath } = useLocation();
|
||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
const node = navIndex[ROUTE_BASE_ID];
|
||||
const main = node;
|
||||
const isDefaultRoute = (item: NavModelItem) =>
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { importDashboard, removeDashboard } from 'app/features/dashboard/state/actions';
|
||||
import { loadPluginDashboards } from 'app/features/plugins/admin/state/actions';
|
||||
import { PluginDashboard, StoreState } from 'app/types';
|
||||
import { PluginDashboard, StoreState, useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import DashboardTable from '../components/DashboardsTable';
|
||||
import { useLoadDataSource } from '../state';
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { DataSourceSettings } from '@grafana/data';
|
||||
import { Card, Tag, useStyles } from '@grafana/ui';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { StoreState, AccessControlAction } from 'app/types';
|
||||
import { StoreState, AccessControlAction, useSelector } from 'app/types';
|
||||
|
||||
import { getDataSources, getDataSourcesCount, useDataSourcesRoutes, useLoadDataSources } from '../state';
|
||||
|
||||
@ -16,7 +15,7 @@ import { DataSourcesListHeader } from './DataSourcesListHeader';
|
||||
export function DataSourcesList() {
|
||||
useLoadDataSources();
|
||||
|
||||
const dataSources = useSelector((state: StoreState) => getDataSources(state.dataSources));
|
||||
const dataSources = useSelector((state) => getDataSources(state.dataSources));
|
||||
const dataSourcesCount = useSelector(({ dataSources }: StoreState) => getDataSourcesCount(dataSources));
|
||||
const hasFetched = useSelector(({ dataSources }: StoreState) => dataSources.hasFetched);
|
||||
const hasCreateRights = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import PageActionBar from 'app/core/components/PageActionBar/PageActionBar';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { AccessControlAction, StoreState } from 'app/types';
|
||||
import { AccessControlAction, StoreState, useSelector, useDispatch } from 'app/types';
|
||||
|
||||
import { getDataSourcesSearchQuery, setDataSourcesSearchQuery, useDataSourcesRoutes } from '../state';
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { AnyAction } from '@reduxjs/toolkit';
|
||||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { DataSourcePluginMeta, DataSourceSettings as DataSourceSettingsType } from '@grafana/data';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { DataSourceSettingsState, ThunkResult } from 'app/types';
|
||||
import { DataSourceSettingsState, useDispatch } from 'app/types';
|
||||
|
||||
import {
|
||||
dataSourceLoaded,
|
||||
@ -85,8 +84,8 @@ export type ViewProps = {
|
||||
onDefaultChange: (isDefault: boolean) => AnyAction;
|
||||
onNameChange: (name: string) => AnyAction;
|
||||
onOptionsChange: (dataSource: DataSourceSettingsType) => AnyAction;
|
||||
onTest: () => ThunkResult<void>;
|
||||
onUpdate: (dataSource: DataSourceSettingsType) => ThunkResult<void>;
|
||||
onTest: () => void;
|
||||
onUpdate: (dataSource: DataSourceSettingsType) => Promise<void>;
|
||||
};
|
||||
|
||||
export function EditDataSourceView({
|
||||
|
@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { DataSourcePluginMeta } from '@grafana/data';
|
||||
import { LinkButton, FilterInput } from '@grafana/ui';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { PluginsErrorsInfo } from 'app/features/plugins/components/PluginsErrorsInfo';
|
||||
import { DataSourcePluginCategory, StoreState } from 'app/types';
|
||||
import { DataSourcePluginCategory, StoreState, useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { DataSourceCategories } from '../components/DataSourceCategories';
|
||||
import { DataSourceTypeCardList } from '../components/DataSourceTypeCardList';
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { DataSourcePluginMeta, DataSourceSettings, NavModelItem, urlUtil } from '@grafana/data';
|
||||
import { cleanUpAction } from 'app/core/actions/cleanUp';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { AccessControlAction, StoreState } from 'app/types';
|
||||
import { AccessControlAction, useDispatch, useSelector } from 'app/types';
|
||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||
|
||||
import { DataSourceRights } from '../types';
|
||||
@ -83,12 +82,12 @@ export const useAddDatasource = () => {
|
||||
export const useUpdateDatasource = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (dataSource: DataSourceSettings) => dispatch(updateDataSource(dataSource));
|
||||
return async (dataSource: DataSourceSettings) => dispatch(updateDataSource(dataSource));
|
||||
};
|
||||
|
||||
export const useDeleteLoadedDataSource = () => {
|
||||
const dispatch = useDispatch();
|
||||
const { name } = useSelector((state: StoreState) => state.dataSources.dataSource);
|
||||
const { name } = useSelector((state) => state.dataSources.dataSource);
|
||||
|
||||
return () => {
|
||||
appEvents.publish(
|
||||
@ -104,7 +103,7 @@ export const useDeleteLoadedDataSource = () => {
|
||||
};
|
||||
|
||||
export const useDataSource = (uid: string) => {
|
||||
return useSelector((state: StoreState) => getDataSource(state.dataSources, uid));
|
||||
return useSelector((state) => getDataSource(state.dataSources, uid));
|
||||
};
|
||||
|
||||
export const useDataSourceExploreUrl = (uid: string) => {
|
||||
@ -116,17 +115,17 @@ export const useDataSourceExploreUrl = (uid: string) => {
|
||||
};
|
||||
|
||||
export const useDataSourceMeta = (pluginType: string): DataSourcePluginMeta => {
|
||||
return useSelector((state: StoreState) => getDataSourceMeta(state.dataSources, pluginType));
|
||||
return useSelector((state) => getDataSourceMeta(state.dataSources, pluginType));
|
||||
};
|
||||
|
||||
export const useDataSourceSettings = () => {
|
||||
return useSelector((state: StoreState) => state.dataSourceSettings);
|
||||
return useSelector((state) => state.dataSourceSettings);
|
||||
};
|
||||
|
||||
export const useDataSourceSettingsNav = (dataSourceId: string, pageId: string | null) => {
|
||||
const dataSource = useDataSource(dataSourceId);
|
||||
const { plugin, loadError, loading } = useDataSourceSettings();
|
||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
const navIndexId = pageId ? `datasource-${pageId}-${dataSourceId}` : `datasource-settings-${dataSourceId}`;
|
||||
|
||||
if (loadError) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { partial } from 'lodash';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { DeepMap, FieldError, useForm } from 'react-hook-form';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { locationUtil, SelectableValue } from '@grafana/data';
|
||||
import { config, locationService, reportInteraction } from '@grafana/runtime';
|
||||
@ -9,7 +8,7 @@ import { Alert, Button, Field, InputControl, Modal, RadioButtonGroup } from '@gr
|
||||
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { removeDashboardToFetchFromLocalStorage } from 'app/features/dashboard/state/initDashboard';
|
||||
import { ExploreId, AccessControlAction } from 'app/types';
|
||||
import { ExploreId, AccessControlAction, useSelector } from 'app/types';
|
||||
|
||||
import { getExploreItemSelector } from '../state/selectors';
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { ToolbarButton } from '@grafana/ui';
|
||||
import { ExploreId } from 'app/types';
|
||||
import { ExploreId, useSelector } from 'app/types';
|
||||
|
||||
import { getExploreItemSelector } from '../state/selectors';
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { useRegisterActions, useKBar, Action, Priority } from 'kbar';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { ExploreId } from 'app/types';
|
||||
import { ExploreId, useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { splitOpen, splitClose } from './state/main';
|
||||
import { runQueries } from './state/query';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { CoreApp, DataQuery, DataSourceInstanceSettings } from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { getNextRefIdChar } from 'app/core/utils/query';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
import { ExploreId } from 'app/types/explore';
|
||||
|
||||
import { getDatasourceSrv } from '../plugins/datasource_srv';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { LoadingState } from '@grafana/data';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { ExploreId, StoreState } from '../../types';
|
||||
import { ExploreId } from '../../types';
|
||||
|
||||
import { ErrorContainer } from './ErrorContainer';
|
||||
|
||||
@ -11,7 +11,7 @@ interface Props {
|
||||
exploreId: ExploreId;
|
||||
}
|
||||
export function ResponseErrorContainer(props: Props) {
|
||||
const queryResponse = useSelector((state: StoreState) => state.explore[props.exploreId]?.queryResponse);
|
||||
const queryResponse = useSelector((state) => state.explore[props.exploreId]?.queryResponse);
|
||||
const queryError = queryResponse?.state === LoadingState.Error ? queryResponse?.error : undefined;
|
||||
|
||||
// Errors with ref ids are shown below the corresponding query
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { TopOfViewRefType } from '@jaegertracing/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView';
|
||||
import React, { RefObject, useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
DataFrame,
|
||||
@ -30,7 +29,7 @@ import { TraceToMetricsData } from 'app/core/components/TraceToMetrics/TraceToMe
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { getTimeZone } from 'app/features/profile/state/selectors';
|
||||
import { TempoQuery } from 'app/plugins/datasource/tempo/types';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
import { ExploreId } from 'app/types/explore';
|
||||
|
||||
import { changePanelState } from '../state/explorePane';
|
||||
@ -138,7 +137,7 @@ export function TraceView(props: Props) {
|
||||
[props.splitOpenFn, traceToLogsOptions, traceToMetricsOptions, props.dataFrames, createFocusSpanLink]
|
||||
);
|
||||
const onSlimViewClicked = useCallback(() => setSlim(!slim), [slim]);
|
||||
const timeZone = useSelector((state: StoreState) => getTimeZone(state.user));
|
||||
const timeZone = useSelector((state) => getTimeZone(state.user));
|
||||
const datasourceType = datasource ? datasource?.type : 'unknown';
|
||||
|
||||
return (
|
||||
@ -218,7 +217,7 @@ function useFocusSpanLink(options: {
|
||||
refId?: string;
|
||||
datasource?: DataSourceApi;
|
||||
}): [string | undefined, (traceId: string, spanId: string) => LinkModel<Field>] {
|
||||
const panelState = useSelector((state: StoreState) => state.explore[options.exploreId]?.panelsState.trace);
|
||||
const panelState = useSelector((state) => state.explore[options.exploreId]?.panelsState.trace);
|
||||
const focusedSpanId = panelState?.spanId;
|
||||
|
||||
const dispatch = useDispatch();
|
||||
@ -230,7 +229,7 @@ function useFocusSpanLink(options: {
|
||||
})
|
||||
);
|
||||
|
||||
const query = useSelector((state: StoreState) =>
|
||||
const query = useSelector((state) =>
|
||||
state.explore[options.exploreId]?.queries.find((query) => query.refId === options.refId)
|
||||
);
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import TracePageSearchBar from '@jaegertracing/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar';
|
||||
import { TopOfViewRefType } from '@jaegertracing/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView';
|
||||
import React, { RefObject, useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { DataFrame, SplitOpen, PanelData } from '@grafana/data';
|
||||
import { Collapse } from '@grafana/ui';
|
||||
import { StoreState } from 'app/types';
|
||||
import { StoreState, useSelector } from 'app/types';
|
||||
import { ExploreId } from 'app/types/explore';
|
||||
|
||||
import { TraceView } from './TraceView';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { ExploreUrlState, serializeStateToUrlParam, SplitOpen, UrlQueryMap } from '@grafana/data';
|
||||
import { DataQuery, ExploreUrlState, serializeStateToUrlParam, SplitOpenOptions, UrlQueryMap } from '@grafana/data';
|
||||
import { DataSourceSrv, locationService } from '@grafana/runtime';
|
||||
import { GetExploreUrlArguments, stopQueryState } from 'app/core/utils/explore';
|
||||
import { PanelModel } from 'app/features/dashboard/state';
|
||||
@ -101,7 +101,7 @@ export const lastSavedUrl: UrlQueryMap = {};
|
||||
* or uses values from options arg. This does only navigation each pane is then responsible for initialization from
|
||||
* the URL.
|
||||
*/
|
||||
export const splitOpen: SplitOpen = (options): ThunkResult<void> => {
|
||||
export const splitOpen = <T extends DataQuery = DataQuery>(options?: SplitOpenOptions<T>): ThunkResult<void> => {
|
||||
return async (dispatch, getState) => {
|
||||
const leftState: ExploreItemState = getState().explore[ExploreId.left];
|
||||
const leftUrlState = getUrlStateFromPaneState(leftState);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { RefreshPicker } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { ExploreId } from '../../types';
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { AlertsFolderView } from '../alerting/unified/AlertsFolderView';
|
||||
|
||||
@ -16,8 +15,8 @@ export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {}
|
||||
|
||||
const FolderAlerting = ({ match }: OwnProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||
const folder = useSelector((state: StoreState) => state.folder);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
const folder = useSelector((state) => state.folder);
|
||||
|
||||
const uid = match.params.uid;
|
||||
const pageNav = getNavModel(navIndex, `folder-alerting-${uid}`, getLoadingNav(1));
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, PanelPluginMeta } from '@grafana/data';
|
||||
import { Button, useStyles2, VerticalGroup } from '@grafana/ui';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { PanelModel } from 'app/features/dashboard/state';
|
||||
import { changeToLibraryPanel } from 'app/features/panel/state/actions';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter';
|
||||
import { LibraryElementDTO } from '../../types';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
|
||||
import { isFetchError } from '@grafana/runtime';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { PanelModel } from 'app/features/dashboard/state';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import {
|
||||
createPanelLibraryErrorNotification,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { CoreApp, GrafanaTheme2, PanelDataSummary, VisualizationSuggestionsBuilder } from '@grafana/data';
|
||||
import { PanelDataErrorViewProps } from '@grafana/runtime';
|
||||
@ -11,6 +10,7 @@ import store from 'app/core/store';
|
||||
import { toggleVizPicker } from 'app/features/dashboard/components/PanelEditor/state/reducers';
|
||||
import { VisualizationSelectPaneTab } from 'app/features/dashboard/components/PanelEditor/types';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { changePanelPlugin } from '../state/actions';
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { DataSourcePluginMeta } from '@grafana/data';
|
||||
import { Button } from '@grafana/ui';
|
||||
import { addDataSource } from 'app/features/datasources/state/actions';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { isDataSourceEditor } from '../../permissions';
|
||||
import { CatalogPlugin } from '../../types';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { ReactElement } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { SelectableValue, GrafanaTheme2 } from '@grafana/data';
|
||||
@ -9,7 +8,7 @@ import { LoadingPlaceholder, Select, RadioButtonGroup, useStyles2, Tooltip } fro
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { StoreState } from 'app/types/store';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { HorizontalGroup } from '../components/HorizontalGroup';
|
||||
import { PluginList } from '../components/PluginList';
|
||||
@ -22,7 +21,7 @@ import { PluginListDisplayMode } from '../types';
|
||||
export default function Browse({ route }: GrafanaRouteComponentProps): ReactElement | null {
|
||||
const location = useLocation();
|
||||
const locationSearch = locationSearchToObject(location.search);
|
||||
const navModel = useSelector((state: StoreState) => getNavModel(state.navIndex, 'plugins'));
|
||||
const navModel = useSelector((state) => getNavModel(state.navIndex, 'plugins'));
|
||||
const { displayMode, setDisplayMode } = useDisplayMode();
|
||||
const styles = useStyles2(getStyles);
|
||||
const history = useHistory();
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { PluginError } from '@grafana/data';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { sortPlugins, Sorters } from '../helpers';
|
||||
import { CatalogPlugin, PluginCatalogStoreState, PluginListDisplayMode } from '../types';
|
||||
import { CatalogPlugin, PluginListDisplayMode } from '../types';
|
||||
|
||||
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions';
|
||||
import { setDisplayMode } from './reducer';
|
||||
@ -55,7 +55,7 @@ export const useGetSingle = (id: string): CatalogPlugin | undefined => {
|
||||
useFetchAll();
|
||||
useFetchDetails(id);
|
||||
|
||||
return useSelector((state: PluginCatalogStoreState) => selectById(state, id));
|
||||
return useSelector((state) => selectById(state, id));
|
||||
};
|
||||
|
||||
export const useGetErrors = (): PluginError[] => {
|
||||
@ -120,7 +120,7 @@ export const useFetchAll = () => {
|
||||
|
||||
export const useFetchDetails = (id: string) => {
|
||||
const dispatch = useDispatch();
|
||||
const plugin = useSelector((state: PluginCatalogStoreState) => selectById(state, id));
|
||||
const plugin = useSelector((state) => selectById(state, id));
|
||||
const isNotFetching = !useSelector(selectIsRequestPending(fetchDetails.typePrefix));
|
||||
const shouldFetch = isNotFetching && plugin && !plugin.details;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import moment from 'moment'; // eslint-disable-line no-restricted-imports
|
||||
import prismjs from 'prismjs';
|
||||
import react from 'react';
|
||||
import reactDom from 'react-dom';
|
||||
import * as reactRedux from 'react-redux';
|
||||
import * as reactRedux from 'react-redux'; // eslint-disable-line no-restricted-imports
|
||||
import * as reactRouter from 'react-router-dom';
|
||||
import * as redux from 'redux';
|
||||
import * as rxjs from 'rxjs';
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { debounce } from 'lodash';
|
||||
import { FormEvent } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { StoreState } from 'app/types';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import {
|
||||
defaultQueryParams,
|
||||
@ -24,7 +23,7 @@ import { hasFilters } from '../utils';
|
||||
const updateLocation = debounce((query) => locationService.partial(query, true), 300);
|
||||
|
||||
export const useSearchQuery = (defaults: Partial<DashboardQuery>) => {
|
||||
const query = useSelector((state: StoreState) => state.searchQuery);
|
||||
const query = useSelector((state) => state.searchQuery);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onQueryChange = (query: string) => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { Input } from '@grafana/ui';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { variableAdapters } from '../adapters';
|
||||
import { VariablePickerProps } from '../pickers/types';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { PanelProps } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
@ -10,6 +9,7 @@ import { parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'
|
||||
import { NOTIFICATIONS_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants';
|
||||
import { initialAsyncRequestState } from 'app/features/alerting/unified/utils/redux';
|
||||
import { AlertmanagerGroup, Matcher } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { AlertGroup } from './AlertGroup';
|
||||
import { AlertGroupPanelOptions } from './types';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { isEmpty, uniq } from 'lodash';
|
||||
import React, { FC, useEffect, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Icon, MultiSelect } from '@grafana/ui';
|
||||
@ -11,6 +10,7 @@ import {
|
||||
isAsyncRequestMapSliceFulfilled,
|
||||
isAsyncRequestMapSlicePending,
|
||||
} from 'app/features/alerting/unified/utils/redux';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { AlertingRule } from 'app/types/unified-alerting';
|
||||
import { PromRuleType } from 'app/types/unified-alerting-dto';
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { sortBy } from 'lodash';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, PanelProps } from '@grafana/data';
|
||||
import {
|
||||
@ -28,7 +27,7 @@ import {
|
||||
} from 'app/features/alerting/unified/utils/datasource';
|
||||
import { flattenRules, getFirstActiveAt } from 'app/features/alerting/unified/utils/rules';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
import { useDispatch, AccessControlAction } from 'app/types';
|
||||
import { PromRuleWithLocation } from 'app/types/unified-alerting';
|
||||
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { take } from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { GrafanaTheme2, InterpolateFunction, PanelProps } from '@grafana/data';
|
||||
import { CustomScrollbar, stylesFactory, useStyles2 } from '@grafana/ui';
|
||||
@ -13,6 +12,7 @@ import impressionSrv from 'app/core/services/impression_srv';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { SearchCard } from 'app/features/search/components/SearchCard';
|
||||
import { DashboardSearchItem } from 'app/features/search/types';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { PanelLayout, PanelOptions } from './models.gen';
|
||||
import { getStyles } from './styles';
|
||||
|
@ -33,6 +33,9 @@ export function configureStore(initialState?: Partial<StoreState>) {
|
||||
return store;
|
||||
}
|
||||
|
||||
export type RootState = ReturnType<ReturnType<typeof configureStore>['getState']>;
|
||||
export type AppDispatch = ReturnType<typeof configureStore>['dispatch'];
|
||||
|
||||
/*
|
||||
function getActionsToIgnoreSerializableCheckOn() {
|
||||
return [
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-restricted-imports */
|
||||
import {
|
||||
Action,
|
||||
AsyncThunk,
|
||||
@ -14,7 +15,7 @@ import {
|
||||
import { ThunkAction, ThunkDispatch as GenericThunkDispatch } from 'redux-thunk';
|
||||
|
||||
import type { createRootReducer } from 'app/core/reducers/root';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
import { AppDispatch, RootState } from 'app/store/configureStore';
|
||||
|
||||
export type StoreState = ReturnType<ReturnType<typeof createRootReducer>>;
|
||||
|
||||
@ -26,9 +27,8 @@ export type ThunkResult<R> = ThunkAction<R, StoreState, undefined, PayloadAction
|
||||
export type ThunkDispatch = GenericThunkDispatch<StoreState, undefined, Action>;
|
||||
|
||||
// Typed useDispatch & useSelector hooks
|
||||
export type AppDispatch = ReturnType<typeof configureStore>['dispatch'];
|
||||
export const useDispatch = () => useDispatchUntyped<AppDispatch>();
|
||||
export const useSelector: TypedUseSelectorHook<StoreState> = useSelectorUntyped;
|
||||
export const useDispatch: () => AppDispatch = useDispatchUntyped;
|
||||
export const useSelector: TypedUseSelectorHook<RootState> = useSelectorUntyped;
|
||||
|
||||
type DefaultThunkApiConfig = { dispatch: AppDispatch; state: StoreState };
|
||||
export const createAsyncThunk = <Returned, ThunkArg = void, ThunkApiConfig extends {} = DefaultThunkApiConfig>(
|
||||
|
Loading…
Reference in New Issue
Block a user