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