mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Routing: Update connections to react router 6 (#94461)
* Update routes * Update test * Remove the useDataSourcesRoutes hook * Remove DataSourcesRoutesContext * Fix imports * Fix more imports * Add default * Betterer
This commit is contained in:
parent
ba3629c01c
commit
e5795c7b6d
@ -3513,8 +3513,7 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "2"],
|
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "2"],
|
||||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "3"],
|
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "3"],
|
||||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "4"],
|
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "4"],
|
||||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "5"],
|
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "5"]
|
||||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "6"]
|
|
||||||
],
|
],
|
||||||
"public/app/features/datasources/state/navModel.ts:5381": [
|
"public/app/features/datasources/state/navModel.ts:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { render, RenderResult, screen } from '@testing-library/react';
|
import { RenderResult, screen } from '@testing-library/react';
|
||||||
import { TestProvider } from 'test/helpers/TestProvider';
|
import { Route, Routes } from 'react-router-dom-v5-compat';
|
||||||
|
import { render } from 'test/test-utils';
|
||||||
|
|
||||||
import { locationService } from '@grafana/runtime';
|
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
import { getMockDataSources } from 'app/features/datasources/__mocks__';
|
import { getMockDataSources } from 'app/features/datasources/__mocks__';
|
||||||
import * as api from 'app/features/datasources/api';
|
import * as api from 'app/features/datasources/api';
|
||||||
@ -11,7 +11,7 @@ import { getPluginsStateMock } from '../plugins/admin/__mocks__';
|
|||||||
|
|
||||||
import Connections from './Connections';
|
import Connections from './Connections';
|
||||||
import { navIndex } from './__mocks__/store.navIndex.mock';
|
import { navIndex } from './__mocks__/store.navIndex.mock';
|
||||||
import { ROUTE_BASE_ID, ROUTES } from './constants';
|
import { ROUTES } from './constants';
|
||||||
|
|
||||||
jest.mock('app/core/services/context_srv');
|
jest.mock('app/core/services/context_srv');
|
||||||
jest.mock('app/features/datasources/api');
|
jest.mock('app/features/datasources/api');
|
||||||
@ -21,15 +21,17 @@ jest.mock('@grafana/runtime', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const renderPage = (
|
const renderPage = (
|
||||||
path = `/${ROUTE_BASE_ID}`,
|
path: string = ROUTES.Base,
|
||||||
store = configureStore({ navIndex, plugins: getPluginsStateMock([]) })
|
store = configureStore({ navIndex, plugins: getPluginsStateMock([]) })
|
||||||
): RenderResult => {
|
): RenderResult => {
|
||||||
locationService.push(path);
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
<TestProvider store={store}>
|
<Routes>
|
||||||
<Connections />
|
<Route path={`${ROUTES.Base}/*`} element={<Connections />} />
|
||||||
</TestProvider>
|
</Routes>,
|
||||||
|
{
|
||||||
|
store,
|
||||||
|
historyOptions: { initialEntries: [path] },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { Route, Switch, useLocation } from 'react-router-dom';
|
import { Navigate, Routes, Route, useLocation } from 'react-router-dom-v5-compat';
|
||||||
import { Navigate } from 'react-router-dom-v5-compat';
|
|
||||||
|
|
||||||
import { DataSourcesRoutesContext } from 'app/features/datasources/state';
|
|
||||||
import { StoreState, useSelector } from 'app/types';
|
import { StoreState, useSelector } from 'app/types';
|
||||||
|
|
||||||
import { ROUTES } from './constants';
|
import { ROUTES } from './constants';
|
||||||
@ -32,39 +30,43 @@ export default function Connections() {
|
|||||||
const isAddNewConnectionPageOverridden = Boolean(navIndex['standalone-plugin-page-/connections/add-new-connection']);
|
const isAddNewConnectionPageOverridden = Boolean(navIndex['standalone-plugin-page-/connections/add-new-connection']);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataSourcesRoutesContext.Provider
|
<Routes>
|
||||||
value={{
|
{/* Redirect to "Add new connection" by default */}
|
||||||
New: ROUTES.DataSourcesNew,
|
<Route caseSensitive path={'/'} element={<Navigate replace to={ROUTES.AddNewConnection} />} />
|
||||||
List: ROUTES.DataSources,
|
{/* The route paths need to be relative to the parent path (ROUTES.Base), so we need to remove that part */}
|
||||||
Edit: ROUTES.DataSourcesEdit,
|
<Route caseSensitive path={ROUTES.DataSources.replace(ROUTES.Base, '')} element={<DataSourcesListPage />} />
|
||||||
Dashboards: ROUTES.DataSourcesDashboards,
|
<Route caseSensitive path={ROUTES.DataSourcesNew.replace(ROUTES.Base, '')} element={<NewDataSourcePage />} />
|
||||||
}}
|
<Route
|
||||||
>
|
caseSensitive
|
||||||
<Switch>
|
path={ROUTES.DataSourcesDetails.replace(ROUTES.Base, '')}
|
||||||
{/* Redirect to "Add new connection" by default */}
|
element={<DataSourceDetailsPage />}
|
||||||
<Route exact sensitive path={ROUTES.Base} component={() => <Navigate replace to={ROUTES.AddNewConnection} />} />
|
/>
|
||||||
<Route exact sensitive path={ROUTES.DataSources} component={DataSourcesListPage} />
|
<Route caseSensitive path={ROUTES.DataSourcesEdit.replace(ROUTES.Base, '')} element={<EditDataSourcePage />} />
|
||||||
<Route exact sensitive path={ROUTES.DataSourcesNew} component={NewDataSourcePage} />
|
<Route
|
||||||
<Route exact sensitive path={ROUTES.DataSourcesDetails} component={DataSourceDetailsPage} />
|
caseSensitive
|
||||||
<Route exact sensitive path={ROUTES.DataSourcesEdit} component={EditDataSourcePage} />
|
path={ROUTES.DataSourcesDashboards.replace(ROUTES.Base, '')}
|
||||||
<Route exact sensitive path={ROUTES.DataSourcesDashboards} component={DataSourceDashboardsPage} />
|
element={<DataSourceDashboardsPage />}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* "Add new connection" page - we don't register a route in case a plugin already registers a standalone page for it */}
|
{/* "Add new connection" page - we don't register a route in case a plugin already registers a standalone page for it */}
|
||||||
{!isAddNewConnectionPageOverridden && (
|
{!isAddNewConnectionPageOverridden && (
|
||||||
<Route exact sensitive path={ROUTES.AddNewConnection} component={AddNewConnectionPage} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Redirect from earlier routes to updated routes */}
|
|
||||||
<Route exact path={ROUTES.ConnectDataOutdated} component={RedirectToAddNewConnection} />
|
|
||||||
<Route
|
<Route
|
||||||
path={`${ROUTES.Base}/your-connections/:page`}
|
caseSensitive
|
||||||
component={() => <Navigate replace to={`${ROUTES.Base}/:page`} />}
|
path={ROUTES.AddNewConnection.replace(ROUTES.Base, '')}
|
||||||
|
element={<AddNewConnectionPage />}
|
||||||
/>
|
/>
|
||||||
<Route path={ROUTES.YourConnectionsOutdated} component={() => <Navigate replace to={ROUTES.DataSources} />} />
|
)}
|
||||||
|
|
||||||
{/* Not found */}
|
{/* Redirect from earlier routes to updated routes */}
|
||||||
<Route component={() => <Navigate replace to="/notfound" />} />
|
<Route path={ROUTES.ConnectDataOutdated.replace(ROUTES.Base, '')} element={<RedirectToAddNewConnection />} />
|
||||||
</Switch>
|
<Route path={`/your-connections/:page`} element={<Navigate replace to={`${ROUTES.Base}/:page`} />} />
|
||||||
</DataSourcesRoutesContext.Provider>
|
<Route
|
||||||
|
path={ROUTES.YourConnectionsOutdated.replace(ROUTES.Base, '')}
|
||||||
|
element={<Navigate replace to={ROUTES.DataSources} />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Not found */}
|
||||||
|
<Route element={<Navigate replace to="/notfound" />} />
|
||||||
|
</Routes>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { NavModel, NavModelItem } from '@grafana/data';
|
import { NavModel, NavModelItem } from '@grafana/data';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
@ -9,7 +9,7 @@ import { useGetSingle } from 'app/features/plugins/admin/state/hooks';
|
|||||||
import { useSelector } from 'app/types';
|
import { useSelector } from 'app/types';
|
||||||
|
|
||||||
export function useDataSourceSettingsNav(pageIdParam?: string) {
|
export function useDataSourceSettingsNav(pageIdParam?: string) {
|
||||||
const { uid } = useParams<{ uid: string }>();
|
const { uid = '' } = useParams<{ uid: string }>();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const datasource = useDataSource(uid);
|
const datasource = useDataSource(uid);
|
||||||
const dataSourceMeta = useDataSourceMeta(datasource.type);
|
const dataSourceMeta = useDataSourceMeta(datasource.type);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { Page } from 'app/core/components/Page/Page';
|
import { Page } from 'app/core/components/Page/Page';
|
||||||
import { DataSourceDashboards } from 'app/features/datasources/components/DataSourceDashboards';
|
import { DataSourceDashboards } from 'app/features/datasources/components/DataSourceDashboards';
|
||||||
@ -6,7 +6,7 @@ import { DataSourceDashboards } from 'app/features/datasources/components/DataSo
|
|||||||
import { useDataSourceSettingsNav } from '../hooks/useDataSourceSettingsNav';
|
import { useDataSourceSettingsNav } from '../hooks/useDataSourceSettingsNav';
|
||||||
|
|
||||||
export function DataSourceDashboardsPage() {
|
export function DataSourceDashboardsPage() {
|
||||||
const { uid } = useParams<{ uid: string }>();
|
const { uid = '' } = useParams<{ uid: string }>();
|
||||||
const { navId, pageNav } = useDataSourceSettingsNav('dashboards');
|
const { navId, pageNav } = useDataSourceSettingsNav('dashboards');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { Alert, Badge } from '@grafana/ui';
|
import { Alert, Badge } from '@grafana/ui';
|
||||||
import { PluginDetailsPage } from 'app/features/plugins/admin/components/PluginDetailsPage';
|
import { PluginDetailsPage } from 'app/features/plugins/admin/components/PluginDetailsPage';
|
||||||
@ -8,7 +8,7 @@ import { ROUTES } from '../constants';
|
|||||||
|
|
||||||
export function DataSourceDetailsPage() {
|
export function DataSourceDetailsPage() {
|
||||||
const overrideNavId = 'standalone-plugin-page-/connections/add-new-connection';
|
const overrideNavId = 'standalone-plugin-page-/connections/add-new-connection';
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id = '' } = useParams<{ id: string }>();
|
||||||
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
const navIndex = useSelector((state: StoreState) => state.navIndex);
|
||||||
const isConnectDataPageOverriden = Boolean(navIndex[overrideNavId]);
|
const isConnectDataPageOverriden = Boolean(navIndex[overrideNavId]);
|
||||||
const navId = isConnectDataPageOverriden ? overrideNavId : 'connections-add-new-connection'; // The nav id changes (gets a prefix) if it is overriden by a plugin
|
const navId = isConnectDataPageOverriden ? overrideNavId : 'connections-add-new-connection'; // The nav id changes (gets a prefix) if it is overriden by a plugin
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import DataSourceTabPage from 'app/features/datasources/components/DataSourceTabPage';
|
import DataSourceTabPage from 'app/features/datasources/components/DataSourceTabPage';
|
||||||
|
|
||||||
export function EditDataSourcePage() {
|
export function EditDataSourcePage() {
|
||||||
const { uid } = useParams<{ uid: string }>();
|
const { uid = '' } = useParams<{ uid: string }>();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const pageId = params.get('page');
|
const pageId = params.get('page');
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
||||||
import { RouteDescriptor } from 'app/core/navigation/types';
|
import { RouteDescriptor } from 'app/core/navigation/types';
|
||||||
|
|
||||||
import { ROUTE_BASE_ID } from './constants';
|
import { ROUTES } from './constants';
|
||||||
|
|
||||||
export function getRoutes(): RouteDescriptor[] {
|
export function getRoutes(): RouteDescriptor[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
path: `/${ROUTE_BASE_ID}`,
|
path: ROUTES.Base,
|
||||||
exact: false,
|
exact: false,
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "Connections"*/ 'app/features/connections/Connections')
|
() => import(/* webpackChunkName: "Connections"*/ 'app/features/connections/Connections')
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState, FormEvent, MouseEvent } from 'react';
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
import { GrafanaTheme2, PluginType } from '@grafana/data';
|
import { GrafanaTheme2, PluginType } from '@grafana/data';
|
||||||
import { useStyles2, LoadingPlaceholder, EmptyState } from '@grafana/ui';
|
import { useStyles2, LoadingPlaceholder, EmptyState } from '@grafana/ui';
|
||||||
@ -38,7 +37,7 @@ export function AddNewConnection() {
|
|||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
const canCreateDataSources = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
const canCreateDataSources = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
||||||
|
|
||||||
const handleSearchChange = (e: React.FormEvent<HTMLInputElement>) => {
|
const handleSearchChange = (e: FormEvent<HTMLInputElement>) => {
|
||||||
setQueryParams({
|
setQueryParams({
|
||||||
search: e.currentTarget.value.toLowerCase(),
|
search: e.currentTarget.value.toLowerCase(),
|
||||||
});
|
});
|
||||||
@ -62,7 +61,7 @@ export function AddNewConnection() {
|
|||||||
[plugins]
|
[plugins]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onClickCardGridItem = (e: React.MouseEvent<HTMLElement>, item: CardGridItem) => {
|
const onClickCardGridItem = (e: MouseEvent<HTMLElement>, item: CardGridItem) => {
|
||||||
if (!canCreateDataSources) {
|
if (!canCreateDataSources) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -2,16 +2,14 @@ import { config } from '@grafana/runtime';
|
|||||||
import { LinkButton } from '@grafana/ui';
|
import { LinkButton } from '@grafana/ui';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
import { Trans } from 'app/core/internationalization';
|
import { Trans } from 'app/core/internationalization';
|
||||||
|
import { ROUTES } from 'app/features/connections/constants';
|
||||||
import { AccessControlAction } from 'app/types';
|
import { AccessControlAction } from 'app/types';
|
||||||
|
|
||||||
import { useDataSourcesRoutes } from '../state';
|
|
||||||
|
|
||||||
export function DataSourceAddButton(): JSX.Element | null {
|
export function DataSourceAddButton(): JSX.Element | null {
|
||||||
const canCreateDataSource = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
const canCreateDataSource = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
|
|
||||||
return canCreateDataSource ? (
|
return canCreateDataSource ? (
|
||||||
<LinkButton icon="plus" href={config.appSubUrl + dataSourcesRoutes.New}>
|
<LinkButton icon="plus" href={config.appSubUrl + ROUTES.DataSourcesNew}>
|
||||||
<Trans i18nKey="data-sources.datasource-add-button.label">Add new data source</Trans>
|
<Trans i18nKey="data-sources.datasource-add-button.label">Add new data source</Trans>
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
) : null;
|
) : null;
|
||||||
|
@ -9,7 +9,8 @@ import { contextSrv } from 'app/core/core';
|
|||||||
import { Trans, t } from 'app/core/internationalization';
|
import { Trans, t } from 'app/core/internationalization';
|
||||||
import { StoreState, AccessControlAction, useSelector } from 'app/types';
|
import { StoreState, AccessControlAction, useSelector } from 'app/types';
|
||||||
|
|
||||||
import { getDataSources, getDataSourcesCount, useDataSourcesRoutes, useLoadDataSources } from '../state';
|
import { ROUTES } from '../../connections/constants';
|
||||||
|
import { getDataSources, getDataSourcesCount, useLoadDataSources } from '../state';
|
||||||
import { trackDataSourcesListViewed } from '../tracking';
|
import { trackDataSourcesListViewed } from '../tracking';
|
||||||
|
|
||||||
import { DataSourcesListCard } from './DataSourcesListCard';
|
import { DataSourcesListCard } from './DataSourcesListCard';
|
||||||
@ -54,7 +55,6 @@ export function DataSourcesListView({
|
|||||||
hasExploreRights,
|
hasExploreRights,
|
||||||
}: ViewProps) {
|
}: ViewProps) {
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -69,7 +69,7 @@ export function DataSourcesListView({
|
|||||||
<EmptyState
|
<EmptyState
|
||||||
variant="call-to-action"
|
variant="call-to-action"
|
||||||
button={
|
button={
|
||||||
<LinkButton disabled={!hasCreateRights} href={dataSourcesRoutes.New} icon="database" size="lg">
|
<LinkButton disabled={!hasCreateRights} href={ROUTES.DataSourcesNew} icon="database" size="lg">
|
||||||
<Trans i18nKey="data-source-list.empty-state.button-title">Add data source</Trans>
|
<Trans i18nKey="data-source-list.empty-state.button-title">Add data source</Trans>
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { DataSourceSettings, GrafanaTheme2 } from '@grafana/data';
|
|||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Card, LinkButton, Stack, Tag, useStyles2 } from '@grafana/ui';
|
import { Card, LinkButton, Stack, Tag, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { useDataSourcesRoutes } from '../state';
|
import { ROUTES } from '../../connections/constants';
|
||||||
import { trackCreateDashboardClicked, trackExploreClicked } from '../tracking';
|
import { trackCreateDashboardClicked, trackExploreClicked } from '../tracking';
|
||||||
import { constructDataSourceExploreUrl } from '../utils';
|
import { constructDataSourceExploreUrl } from '../utils';
|
||||||
|
|
||||||
@ -16,8 +16,7 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function DataSourcesListCard({ dataSource, hasWriteRights, hasExploreRights }: Props) {
|
export function DataSourcesListCard({ dataSource, hasWriteRights, hasExploreRights }: Props) {
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
const dsLink = config.appSubUrl + ROUTES.DataSourcesEdit.replace(/:uid/gi, dataSource.uid);
|
||||||
const dsLink = config.appSubUrl + dataSourcesRoutes.Edit.replace(/:uid/gi, dataSource.uid);
|
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AnyAction } from 'redux';
|
import { Action } from 'redux';
|
||||||
|
|
||||||
import { DataSourcePluginMeta, PluginType } from '@grafana/data';
|
import { DataSourcePluginMeta, PluginType } from '@grafana/data';
|
||||||
import { LinkButton, FilterInput } from '@grafana/ui';
|
import { LinkButton, FilterInput } from '@grafana/ui';
|
||||||
@ -6,6 +6,7 @@ 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, useDispatch, useSelector } from 'app/types';
|
import { DataSourcePluginCategory, StoreState, useDispatch, useSelector } from 'app/types';
|
||||||
|
|
||||||
|
import { ROUTES } from '../../connections/constants';
|
||||||
import { DataSourceCategories } from '../components/DataSourceCategories';
|
import { DataSourceCategories } from '../components/DataSourceCategories';
|
||||||
import { DataSourceTypeCardList } from '../components/DataSourceTypeCardList';
|
import { DataSourceTypeCardList } from '../components/DataSourceTypeCardList';
|
||||||
import {
|
import {
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
useLoadDataSourcePlugins,
|
useLoadDataSourcePlugins,
|
||||||
getFilteredDataSourcePlugins,
|
getFilteredDataSourcePlugins,
|
||||||
setDataSourceTypeSearchQuery,
|
setDataSourceTypeSearchQuery,
|
||||||
useDataSourcesRoutes,
|
|
||||||
} from '../state';
|
} from '../state';
|
||||||
|
|
||||||
export function NewDataSource() {
|
export function NewDataSource() {
|
||||||
@ -45,7 +45,7 @@ export type ViewProps = {
|
|||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
onAddDataSource: (dataSource: DataSourcePluginMeta) => void;
|
onAddDataSource: (dataSource: DataSourcePluginMeta) => void;
|
||||||
onSetSearchQuery: (q: string) => AnyAction;
|
onSetSearchQuery: (q: string) => Action;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function NewDataSourceView({
|
export function NewDataSourceView({
|
||||||
@ -56,8 +56,6 @@ export function NewDataSourceView({
|
|||||||
onAddDataSource,
|
onAddDataSource,
|
||||||
onSetSearchQuery,
|
onSetSearchQuery,
|
||||||
}: ViewProps) {
|
}: ViewProps) {
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <PageLoader />;
|
return <PageLoader />;
|
||||||
}
|
}
|
||||||
@ -68,7 +66,7 @@ export function NewDataSourceView({
|
|||||||
<div className="page-action-bar">
|
<div className="page-action-bar">
|
||||||
<FilterInput value={searchQuery} onChange={onSetSearchQuery} placeholder="Filter by name or type" />
|
<FilterInput value={searchQuery} onChange={onSetSearchQuery} placeholder="Filter by name or type" />
|
||||||
<div className="page-action-bar__spacer" />
|
<div className="page-action-bar__spacer" />
|
||||||
<LinkButton href={dataSourcesRoutes.List} fill="outline" variant="secondary" icon="arrow-left">
|
<LinkButton href={ROUTES.DataSources} fill="outline" variant="secondary" icon="arrow-left">
|
||||||
Cancel
|
Cancel
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { createContext } from 'react';
|
|
||||||
|
|
||||||
import { DATASOURCES_ROUTES } from '../constants';
|
|
||||||
import { DataSourcesRoutes } from '../types';
|
|
||||||
|
|
||||||
// The purpose of this context is to be able to override the data-sources routes (used for links for example) used under
|
|
||||||
// the app/features/datasources modules, so we can reuse them more easily in different parts of the application (e.g. under Connections)
|
|
||||||
export const DataSourcesRoutesContext = createContext<DataSourcesRoutes>(DATASOURCES_ROUTES);
|
|
@ -1,4 +1,4 @@
|
|||||||
import { useContext, useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { DataSourcePluginMeta, DataSourceSettings } from '@grafana/data';
|
import { DataSourcePluginMeta, DataSourceSettings } from '@grafana/data';
|
||||||
import { cleanUpAction } from 'app/core/actions/cleanUp';
|
import { cleanUpAction } from 'app/core/actions/cleanUp';
|
||||||
@ -7,6 +7,7 @@ import { contextSrv } from 'app/core/core';
|
|||||||
import { AccessControlAction, useDispatch, useSelector } from 'app/types';
|
import { AccessControlAction, useDispatch, useSelector } from 'app/types';
|
||||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||||
|
|
||||||
|
import { ROUTES } from '../../connections/constants';
|
||||||
import { DataSourceRights } from '../types';
|
import { DataSourceRights } from '../types';
|
||||||
import { constructDataSourceExploreUrl } from '../utils';
|
import { constructDataSourceExploreUrl } from '../utils';
|
||||||
|
|
||||||
@ -20,7 +21,6 @@ import {
|
|||||||
updateDataSource,
|
updateDataSource,
|
||||||
deleteLoadedDataSource,
|
deleteLoadedDataSource,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { DataSourcesRoutesContext } from './contexts';
|
|
||||||
import { initialDataSourceSettingsState } from './reducers';
|
import { initialDataSourceSettingsState } from './reducers';
|
||||||
import { getDataSource, getDataSourceMeta } from './selectors';
|
import { getDataSource, getDataSourceMeta } from './selectors';
|
||||||
|
|
||||||
@ -42,9 +42,8 @@ export const useInitDataSourceSettings = (uid: string) => {
|
|||||||
|
|
||||||
export const useTestDataSource = (uid: string) => {
|
export const useTestDataSource = (uid: string) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
|
|
||||||
return () => dispatch(testDataSource(uid, dataSourcesRoutes.Edit));
|
return () => dispatch(testDataSource(uid, ROUTES.DataSourcesEdit));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useLoadDataSources = () => {
|
export const useLoadDataSources = () => {
|
||||||
@ -77,10 +76,9 @@ export const useLoadDataSourcePlugins = () => {
|
|||||||
|
|
||||||
export const useAddDatasource = () => {
|
export const useAddDatasource = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
|
|
||||||
return (plugin: DataSourcePluginMeta) => {
|
return (plugin: DataSourcePluginMeta) => {
|
||||||
dispatch(addDataSource(plugin, dataSourcesRoutes.Edit));
|
dispatch(addDataSource(plugin, ROUTES.DataSourcesEdit));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,7 +134,3 @@ export const useDataSourceRights = (uid: string): DataSourceRights => {
|
|||||||
hasDeleteRights,
|
hasDeleteRights,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDataSourcesRoutes = () => {
|
|
||||||
return useContext(DataSourcesRoutesContext);
|
|
||||||
};
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
export * from './actions';
|
export * from './actions';
|
||||||
export * from './buildCategories';
|
export * from './buildCategories';
|
||||||
export * from './contexts';
|
|
||||||
export * from './hooks';
|
export * from './hooks';
|
||||||
export * from './navModel';
|
export * from './navModel';
|
||||||
export * from './reducers';
|
export * from './reducers';
|
||||||
|
@ -4,7 +4,8 @@ import * as React from 'react';
|
|||||||
import { DataSourcePluginMeta } from '@grafana/data';
|
import { DataSourcePluginMeta } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Button } from '@grafana/ui';
|
import { Button } from '@grafana/ui';
|
||||||
import { useDataSourcesRoutes, addDataSource } from 'app/features/datasources/state';
|
import { ROUTES } from 'app/features/connections/constants';
|
||||||
|
import { addDataSource } from 'app/features/datasources/state';
|
||||||
import { useDispatch } from 'app/types';
|
import { useDispatch } from 'app/types';
|
||||||
|
|
||||||
import { isDataSourceEditor } from '../../permissions';
|
import { isDataSourceEditor } from '../../permissions';
|
||||||
@ -16,15 +17,14 @@ type Props = {
|
|||||||
|
|
||||||
export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement | null {
|
export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement | null {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
|
||||||
const onAddDataSource = useCallback(() => {
|
const onAddDataSource = useCallback(() => {
|
||||||
const meta = {
|
const meta = {
|
||||||
name: plugin.name,
|
name: plugin.name,
|
||||||
id: plugin.id,
|
id: plugin.id,
|
||||||
} as DataSourcePluginMeta;
|
} as DataSourcePluginMeta;
|
||||||
|
|
||||||
dispatch(addDataSource(meta, dataSourcesRoutes.Edit));
|
dispatch(addDataSource(meta, ROUTES.DataSourcesEdit));
|
||||||
}, [dispatch, plugin, dataSourcesRoutes]);
|
}, [dispatch, plugin]);
|
||||||
|
|
||||||
if (!isDataSourceEditor()) {
|
if (!isDataSourceEditor()) {
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
Reference in New Issue
Block a user