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 ...\`)", "3"],
|
||||
[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 ...\`)", "6"]
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "5"]
|
||||
],
|
||||
"public/app/features/datasources/state/navModel.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { render, RenderResult, screen } from '@testing-library/react';
|
||||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
import { RenderResult, screen } from '@testing-library/react';
|
||||
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 { getMockDataSources } from 'app/features/datasources/__mocks__';
|
||||
import * as api from 'app/features/datasources/api';
|
||||
@ -11,7 +11,7 @@ import { getPluginsStateMock } from '../plugins/admin/__mocks__';
|
||||
|
||||
import Connections from './Connections';
|
||||
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/features/datasources/api');
|
||||
@ -21,15 +21,17 @@ jest.mock('@grafana/runtime', () => ({
|
||||
}));
|
||||
|
||||
const renderPage = (
|
||||
path = `/${ROUTE_BASE_ID}`,
|
||||
path: string = ROUTES.Base,
|
||||
store = configureStore({ navIndex, plugins: getPluginsStateMock([]) })
|
||||
): RenderResult => {
|
||||
locationService.push(path);
|
||||
|
||||
return render(
|
||||
<TestProvider store={store}>
|
||||
<Connections />
|
||||
</TestProvider>
|
||||
<Routes>
|
||||
<Route path={`${ROUTES.Base}/*`} element={<Connections />} />
|
||||
</Routes>,
|
||||
{
|
||||
store,
|
||||
historyOptions: { initialEntries: [path] },
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Route, Switch, useLocation } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
import { Navigate, Routes, Route, useLocation } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { DataSourcesRoutesContext } from 'app/features/datasources/state';
|
||||
import { StoreState, useSelector } from 'app/types';
|
||||
|
||||
import { ROUTES } from './constants';
|
||||
@ -32,39 +30,43 @@ export default function Connections() {
|
||||
const isAddNewConnectionPageOverridden = Boolean(navIndex['standalone-plugin-page-/connections/add-new-connection']);
|
||||
|
||||
return (
|
||||
<DataSourcesRoutesContext.Provider
|
||||
value={{
|
||||
New: ROUTES.DataSourcesNew,
|
||||
List: ROUTES.DataSources,
|
||||
Edit: ROUTES.DataSourcesEdit,
|
||||
Dashboards: ROUTES.DataSourcesDashboards,
|
||||
}}
|
||||
>
|
||||
<Switch>
|
||||
{/* Redirect to "Add new connection" by default */}
|
||||
<Route exact sensitive path={ROUTES.Base} component={() => <Navigate replace to={ROUTES.AddNewConnection} />} />
|
||||
<Route exact sensitive path={ROUTES.DataSources} component={DataSourcesListPage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesNew} component={NewDataSourcePage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesDetails} component={DataSourceDetailsPage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesEdit} component={EditDataSourcePage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesDashboards} component={DataSourceDashboardsPage} />
|
||||
<Routes>
|
||||
{/* Redirect to "Add new connection" by default */}
|
||||
<Route caseSensitive path={'/'} element={<Navigate replace to={ROUTES.AddNewConnection} />} />
|
||||
{/* The route paths need to be relative to the parent path (ROUTES.Base), so we need to remove that part */}
|
||||
<Route caseSensitive path={ROUTES.DataSources.replace(ROUTES.Base, '')} element={<DataSourcesListPage />} />
|
||||
<Route caseSensitive path={ROUTES.DataSourcesNew.replace(ROUTES.Base, '')} element={<NewDataSourcePage />} />
|
||||
<Route
|
||||
caseSensitive
|
||||
path={ROUTES.DataSourcesDetails.replace(ROUTES.Base, '')}
|
||||
element={<DataSourceDetailsPage />}
|
||||
/>
|
||||
<Route caseSensitive path={ROUTES.DataSourcesEdit.replace(ROUTES.Base, '')} element={<EditDataSourcePage />} />
|
||||
<Route
|
||||
caseSensitive
|
||||
path={ROUTES.DataSourcesDashboards.replace(ROUTES.Base, '')}
|
||||
element={<DataSourceDashboardsPage />}
|
||||
/>
|
||||
|
||||
{/* "Add new connection" page - we don't register a route in case a plugin already registers a standalone page for it */}
|
||||
{!isAddNewConnectionPageOverridden && (
|
||||
<Route exact sensitive path={ROUTES.AddNewConnection} component={AddNewConnectionPage} />
|
||||
)}
|
||||
|
||||
{/* Redirect from earlier routes to updated routes */}
|
||||
<Route exact path={ROUTES.ConnectDataOutdated} component={RedirectToAddNewConnection} />
|
||||
{/* "Add new connection" page - we don't register a route in case a plugin already registers a standalone page for it */}
|
||||
{!isAddNewConnectionPageOverridden && (
|
||||
<Route
|
||||
path={`${ROUTES.Base}/your-connections/:page`}
|
||||
component={() => <Navigate replace to={`${ROUTES.Base}/:page`} />}
|
||||
caseSensitive
|
||||
path={ROUTES.AddNewConnection.replace(ROUTES.Base, '')}
|
||||
element={<AddNewConnectionPage />}
|
||||
/>
|
||||
<Route path={ROUTES.YourConnectionsOutdated} component={() => <Navigate replace to={ROUTES.DataSources} />} />
|
||||
)}
|
||||
|
||||
{/* Not found */}
|
||||
<Route component={() => <Navigate replace to="/notfound" />} />
|
||||
</Switch>
|
||||
</DataSourcesRoutesContext.Provider>
|
||||
{/* Redirect from earlier routes to updated routes */}
|
||||
<Route path={ROUTES.ConnectDataOutdated.replace(ROUTES.Base, '')} element={<RedirectToAddNewConnection />} />
|
||||
<Route path={`/your-connections/:page`} element={<Navigate replace to={`${ROUTES.Base}/:page`} />} />
|
||||
<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 { getDataSourceSrv } from '@grafana/runtime';
|
||||
@ -9,7 +9,7 @@ import { useGetSingle } from 'app/features/plugins/admin/state/hooks';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
export function useDataSourceSettingsNav(pageIdParam?: string) {
|
||||
const { uid } = useParams<{ uid: string }>();
|
||||
const { uid = '' } = useParams<{ uid: string }>();
|
||||
const location = useLocation();
|
||||
const datasource = useDataSource(uid);
|
||||
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 { DataSourceDashboards } from 'app/features/datasources/components/DataSourceDashboards';
|
||||
@ -6,7 +6,7 @@ import { DataSourceDashboards } from 'app/features/datasources/components/DataSo
|
||||
import { useDataSourceSettingsNav } from '../hooks/useDataSourceSettingsNav';
|
||||
|
||||
export function DataSourceDashboardsPage() {
|
||||
const { uid } = useParams<{ uid: string }>();
|
||||
const { uid = '' } = useParams<{ uid: string }>();
|
||||
const { navId, pageNav } = useDataSourceSettingsNav('dashboards');
|
||||
|
||||
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 { PluginDetailsPage } from 'app/features/plugins/admin/components/PluginDetailsPage';
|
||||
@ -8,7 +8,7 @@ import { ROUTES } from '../constants';
|
||||
|
||||
export function DataSourceDetailsPage() {
|
||||
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 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
|
||||
|
@ -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';
|
||||
|
||||
export function EditDataSourcePage() {
|
||||
const { uid } = useParams<{ uid: string }>();
|
||||
const { uid = '' } = useParams<{ uid: string }>();
|
||||
const location = useLocation();
|
||||
const params = new URLSearchParams(location.search);
|
||||
const pageId = params.get('page');
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
||||
import { RouteDescriptor } from 'app/core/navigation/types';
|
||||
|
||||
import { ROUTE_BASE_ID } from './constants';
|
||||
import { ROUTES } from './constants';
|
||||
|
||||
export function getRoutes(): RouteDescriptor[] {
|
||||
return [
|
||||
{
|
||||
path: `/${ROUTE_BASE_ID}`,
|
||||
path: ROUTES.Base,
|
||||
exact: false,
|
||||
component: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "Connections"*/ 'app/features/connections/Connections')
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useMemo, useState } from 'react';
|
||||
import * as React from 'react';
|
||||
import { useMemo, useState, FormEvent, MouseEvent } from 'react';
|
||||
|
||||
import { GrafanaTheme2, PluginType } from '@grafana/data';
|
||||
import { useStyles2, LoadingPlaceholder, EmptyState } from '@grafana/ui';
|
||||
@ -38,7 +37,7 @@ export function AddNewConnection() {
|
||||
const styles = useStyles2(getStyles);
|
||||
const canCreateDataSources = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
||||
|
||||
const handleSearchChange = (e: React.FormEvent<HTMLInputElement>) => {
|
||||
const handleSearchChange = (e: FormEvent<HTMLInputElement>) => {
|
||||
setQueryParams({
|
||||
search: e.currentTarget.value.toLowerCase(),
|
||||
});
|
||||
@ -62,7 +61,7 @@ export function AddNewConnection() {
|
||||
[plugins]
|
||||
);
|
||||
|
||||
const onClickCardGridItem = (e: React.MouseEvent<HTMLElement>, item: CardGridItem) => {
|
||||
const onClickCardGridItem = (e: MouseEvent<HTMLElement>, item: CardGridItem) => {
|
||||
if (!canCreateDataSources) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -2,16 +2,14 @@ import { config } from '@grafana/runtime';
|
||||
import { LinkButton } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { ROUTES } from 'app/features/connections/constants';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { useDataSourcesRoutes } from '../state';
|
||||
|
||||
export function DataSourceAddButton(): JSX.Element | null {
|
||||
const canCreateDataSource = contextSrv.hasPermission(AccessControlAction.DataSourcesCreate);
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
|
||||
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>
|
||||
</LinkButton>
|
||||
) : null;
|
||||
|
@ -9,7 +9,8 @@ import { contextSrv } from 'app/core/core';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
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 { DataSourcesListCard } from './DataSourcesListCard';
|
||||
@ -54,7 +55,6 @@ export function DataSourcesListView({
|
||||
hasExploreRights,
|
||||
}: ViewProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
@ -69,7 +69,7 @@ export function DataSourcesListView({
|
||||
<EmptyState
|
||||
variant="call-to-action"
|
||||
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>
|
||||
</LinkButton>
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { DataSourceSettings, GrafanaTheme2 } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Card, LinkButton, Stack, Tag, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { useDataSourcesRoutes } from '../state';
|
||||
import { ROUTES } from '../../connections/constants';
|
||||
import { trackCreateDashboardClicked, trackExploreClicked } from '../tracking';
|
||||
import { constructDataSourceExploreUrl } from '../utils';
|
||||
|
||||
@ -16,8 +16,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export function DataSourcesListCard({ dataSource, hasWriteRights, hasExploreRights }: Props) {
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
const dsLink = config.appSubUrl + dataSourcesRoutes.Edit.replace(/:uid/gi, dataSource.uid);
|
||||
const dsLink = config.appSubUrl + ROUTES.DataSourcesEdit.replace(/:uid/gi, dataSource.uid);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AnyAction } from 'redux';
|
||||
import { Action } from 'redux';
|
||||
|
||||
import { DataSourcePluginMeta, PluginType } from '@grafana/data';
|
||||
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 { DataSourcePluginCategory, StoreState, useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { ROUTES } from '../../connections/constants';
|
||||
import { DataSourceCategories } from '../components/DataSourceCategories';
|
||||
import { DataSourceTypeCardList } from '../components/DataSourceTypeCardList';
|
||||
import {
|
||||
@ -13,7 +14,6 @@ import {
|
||||
useLoadDataSourcePlugins,
|
||||
getFilteredDataSourcePlugins,
|
||||
setDataSourceTypeSearchQuery,
|
||||
useDataSourcesRoutes,
|
||||
} from '../state';
|
||||
|
||||
export function NewDataSource() {
|
||||
@ -45,7 +45,7 @@ export type ViewProps = {
|
||||
searchQuery: string;
|
||||
isLoading: boolean;
|
||||
onAddDataSource: (dataSource: DataSourcePluginMeta) => void;
|
||||
onSetSearchQuery: (q: string) => AnyAction;
|
||||
onSetSearchQuery: (q: string) => Action;
|
||||
};
|
||||
|
||||
export function NewDataSourceView({
|
||||
@ -56,8 +56,6 @@ export function NewDataSourceView({
|
||||
onAddDataSource,
|
||||
onSetSearchQuery,
|
||||
}: ViewProps) {
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
|
||||
if (isLoading) {
|
||||
return <PageLoader />;
|
||||
}
|
||||
@ -68,7 +66,7 @@ export function NewDataSourceView({
|
||||
<div className="page-action-bar">
|
||||
<FilterInput value={searchQuery} onChange={onSetSearchQuery} placeholder="Filter by name or type" />
|
||||
<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
|
||||
</LinkButton>
|
||||
</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 { cleanUpAction } from 'app/core/actions/cleanUp';
|
||||
@ -7,6 +7,7 @@ import { contextSrv } from 'app/core/core';
|
||||
import { AccessControlAction, useDispatch, useSelector } from 'app/types';
|
||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||
|
||||
import { ROUTES } from '../../connections/constants';
|
||||
import { DataSourceRights } from '../types';
|
||||
import { constructDataSourceExploreUrl } from '../utils';
|
||||
|
||||
@ -20,7 +21,6 @@ import {
|
||||
updateDataSource,
|
||||
deleteLoadedDataSource,
|
||||
} from './actions';
|
||||
import { DataSourcesRoutesContext } from './contexts';
|
||||
import { initialDataSourceSettingsState } from './reducers';
|
||||
import { getDataSource, getDataSourceMeta } from './selectors';
|
||||
|
||||
@ -42,9 +42,8 @@ export const useInitDataSourceSettings = (uid: string) => {
|
||||
|
||||
export const useTestDataSource = (uid: string) => {
|
||||
const dispatch = useDispatch();
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
|
||||
return () => dispatch(testDataSource(uid, dataSourcesRoutes.Edit));
|
||||
return () => dispatch(testDataSource(uid, ROUTES.DataSourcesEdit));
|
||||
};
|
||||
|
||||
export const useLoadDataSources = () => {
|
||||
@ -77,10 +76,9 @@ export const useLoadDataSourcePlugins = () => {
|
||||
|
||||
export const useAddDatasource = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
|
||||
return (plugin: DataSourcePluginMeta) => {
|
||||
dispatch(addDataSource(plugin, dataSourcesRoutes.Edit));
|
||||
dispatch(addDataSource(plugin, ROUTES.DataSourcesEdit));
|
||||
};
|
||||
};
|
||||
|
||||
@ -136,7 +134,3 @@ export const useDataSourceRights = (uid: string): DataSourceRights => {
|
||||
hasDeleteRights,
|
||||
};
|
||||
};
|
||||
|
||||
export const useDataSourcesRoutes = () => {
|
||||
return useContext(DataSourcesRoutesContext);
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
export * from './actions';
|
||||
export * from './buildCategories';
|
||||
export * from './contexts';
|
||||
export * from './hooks';
|
||||
export * from './navModel';
|
||||
export * from './reducers';
|
||||
|
@ -4,7 +4,8 @@ import * as React from 'react';
|
||||
import { DataSourcePluginMeta } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
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 { isDataSourceEditor } from '../../permissions';
|
||||
@ -16,15 +17,14 @@ type Props = {
|
||||
|
||||
export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement | null {
|
||||
const dispatch = useDispatch();
|
||||
const dataSourcesRoutes = useDataSourcesRoutes();
|
||||
const onAddDataSource = useCallback(() => {
|
||||
const meta = {
|
||||
name: plugin.name,
|
||||
id: plugin.id,
|
||||
} as DataSourcePluginMeta;
|
||||
|
||||
dispatch(addDataSource(meta, dataSourcesRoutes.Edit));
|
||||
}, [dispatch, plugin, dataSourcesRoutes]);
|
||||
dispatch(addDataSource(meta, ROUTES.DataSourcesEdit));
|
||||
}, [dispatch, plugin]);
|
||||
|
||||
if (!isDataSourceEditor()) {
|
||||
return null;
|
||||
|
Loading…
Reference in New Issue
Block a user