mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Datasources: Cleanup unused code from datasources (#73360)
* remove unused datasource pages * move useDataSourceSettingsNav from datasources to connections without any modification in the code yet The reason for this is that its only usage is in this file, so we are going to merge it with the other useDataSourceSettingsNav hook in the next commit. * merge two useDataSourceSettingsNav's and rename consts and remove duplicated calls * simplify useDataSourceSettingsNav
This commit is contained in:
@@ -1,26 +1,70 @@
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
useDataSource,
|
||||
useDataSourceSettingsNav as useDataSourceSettingsNavOriginal,
|
||||
} from 'app/features/datasources/state/hooks';
|
||||
import { NavModel, NavModelItem } from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { useDataSource, useDataSourceSettings } from 'app/features/datasources/state/hooks';
|
||||
import { getDataSourceLoadingNav, buildNavModel, getDataSourceNav } from 'app/features/datasources/state/navModel';
|
||||
import { useGetSingle } from 'app/features/plugins/admin/state/hooks';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
// We are extending the original useDataSourceSettingsNav in the following ways:
|
||||
// - changing the URL of the nav items to point to Connections
|
||||
// - setting the parent nav item
|
||||
export function useDataSourceSettingsNav(pageId?: string) {
|
||||
export function useDataSourceSettingsNav(pageIdParam?: string) {
|
||||
const { uid } = useParams<{ uid: string }>();
|
||||
const location = useLocation();
|
||||
const datasource = useDataSource(uid);
|
||||
const datasourcePlugin = useGetSingle(datasource.type);
|
||||
const params = new URLSearchParams(location.search);
|
||||
const nav = useDataSourceSettingsNavOriginal(uid, pageId || params.get('page'));
|
||||
const pageNav = {
|
||||
...nav.main,
|
||||
const pageId = pageIdParam || params.get('page');
|
||||
|
||||
const { plugin, loadError, loading } = useDataSourceSettings();
|
||||
const dsi = getDataSourceSrv()?.getInstanceSettings(uid);
|
||||
const hasAlertingEnabled = Boolean(dsi?.meta?.alerting ?? false);
|
||||
const isAlertManagerDatasource = dsi?.type === 'alertmanager';
|
||||
const alertingSupported = hasAlertingEnabled || isAlertManagerDatasource;
|
||||
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
const navIndexId = pageId ? `datasource-${pageId}-${uid}` : `datasource-settings-${uid}`;
|
||||
let pageNav: NavModel = {
|
||||
node: {
|
||||
text: 'Data Source Nav Node',
|
||||
},
|
||||
main: {
|
||||
text: 'Data Source Nav Node',
|
||||
},
|
||||
};
|
||||
|
||||
if (loadError) {
|
||||
const node: NavModelItem = {
|
||||
text: loadError,
|
||||
subTitle: 'Data Source Error',
|
||||
icon: 'exclamation-triangle',
|
||||
};
|
||||
|
||||
pageNav = {
|
||||
node: node,
|
||||
main: node,
|
||||
};
|
||||
}
|
||||
|
||||
if (loading || !plugin) {
|
||||
pageNav = getNavModel(navIndex, navIndexId, getDataSourceLoadingNav('settings'));
|
||||
}
|
||||
|
||||
if (plugin) {
|
||||
pageNav = getNavModel(
|
||||
navIndex,
|
||||
navIndexId,
|
||||
getDataSourceNav(buildNavModel(datasource, plugin), pageId || 'settings')
|
||||
);
|
||||
}
|
||||
|
||||
const connectionsPageNav = {
|
||||
...pageNav.main,
|
||||
dataSourcePluginName: datasourcePlugin?.name || plugin?.meta.name || '',
|
||||
active: true,
|
||||
text: datasource.name,
|
||||
subTitle: `Type: ${datasourcePlugin?.name}`,
|
||||
children: (nav.main.children || []).map((navModelItem) => ({
|
||||
children: (pageNav.main.children || []).map((navModelItem) => ({
|
||||
...navModelItem,
|
||||
url: navModelItem.url?.replace('datasources/edit/', '/connections/datasources/edit/'),
|
||||
})),
|
||||
@@ -28,7 +72,9 @@ export function useDataSourceSettingsNav(pageId?: string) {
|
||||
|
||||
return {
|
||||
navId: 'connections-datasources',
|
||||
pageNav,
|
||||
dataSourceHeader: nav.dataSourceHeader,
|
||||
pageNav: connectionsPageNav,
|
||||
dataSourceHeader: {
|
||||
alertingSupported,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { Store } from 'redux';
|
||||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
|
||||
import { setAngularLoader } from '@grafana/runtime';
|
||||
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
|
||||
import { navIndex, getMockDataSource } from '../__mocks__';
|
||||
import * as api from '../api';
|
||||
import { initialState as dataSourcesInitialState } from '../state';
|
||||
|
||||
import DataSourceDashboardsPage from './DataSourceDashboardsPage';
|
||||
|
||||
jest.mock('../api');
|
||||
jest.mock('app/core/services/context_srv', () => ({
|
||||
contextSrv: {
|
||||
hasPermission: () => true,
|
||||
hasPermissionInMetadata: () => true,
|
||||
},
|
||||
}));
|
||||
|
||||
const setup = (uid: string, store: Store) =>
|
||||
render(
|
||||
<TestProvider store={store}>
|
||||
<DataSourceDashboardsPage
|
||||
{...getRouteComponentProps({
|
||||
// @ts-ignore
|
||||
match: {
|
||||
params: {
|
||||
uid,
|
||||
},
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</TestProvider>
|
||||
);
|
||||
|
||||
describe('<DataSourceDashboardsPage>', () => {
|
||||
const uid = 'foo';
|
||||
const dataSourceName = 'My DataSource';
|
||||
const dataSource = getMockDataSource<{}>({ uid, name: dataSourceName });
|
||||
let store: Store;
|
||||
|
||||
beforeAll(() => {
|
||||
setAngularLoader({
|
||||
load: () => ({
|
||||
destroy: jest.fn(),
|
||||
digest: jest.fn(),
|
||||
getScope: () => ({ $watch: () => {} }),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
api.getDataSourceByIdOrUid = jest.fn().mockResolvedValue(dataSource);
|
||||
|
||||
store = configureStore({
|
||||
dataSources: {
|
||||
...dataSourcesInitialState,
|
||||
dataSource: dataSource,
|
||||
},
|
||||
navIndex: {
|
||||
...navIndex,
|
||||
[`datasource-dashboards-${uid}`]: {
|
||||
id: `datasource-dashboards-${uid}`,
|
||||
text: dataSourceName,
|
||||
icon: 'list-ul',
|
||||
url: `/datasources/edit/${uid}/dashboards`,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the dashboards page without an issue', async () => {
|
||||
setup(uid, store);
|
||||
|
||||
expect(await screen.findByText(dataSourceName)).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
|
||||
import { DataSourceDashboards } from '../components/DataSourceDashboards';
|
||||
import { useDataSourceSettingsNav } from '../state';
|
||||
|
||||
export interface Props extends GrafanaRouteComponentProps<{ uid: string }> {}
|
||||
|
||||
export function DataSourceDashboardsPage(props: Props) {
|
||||
const uid = props.match.params.uid;
|
||||
const nav = useDataSourceSettingsNav(uid, 'dashboards');
|
||||
|
||||
return (
|
||||
<Page navId="datasources" pageNav={nav.main}>
|
||||
<Page.Contents>
|
||||
<DataSourceDashboards uid={uid} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default DataSourceDashboardsPage;
|
||||
@@ -1,143 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
|
||||
import { LayoutModes } from '@grafana/data';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
import { navIndex, getMockDataSources } from '../__mocks__';
|
||||
import { getDataSources } from '../api';
|
||||
import { initialState } from '../state';
|
||||
|
||||
import { DataSourcesListPage } from './DataSourcesListPage';
|
||||
|
||||
jest.mock('app/core/services/context_srv');
|
||||
jest.mock('../api', () => ({
|
||||
...jest.requireActual('../api'),
|
||||
getDataSources: jest.fn().mockResolvedValue([]),
|
||||
}));
|
||||
|
||||
const getDataSourcesMock = getDataSources as jest.Mock;
|
||||
|
||||
const setup = (options: { isSortAscending: boolean }) => {
|
||||
const storeState = {
|
||||
dataSources: {
|
||||
...initialState,
|
||||
layoutMode: LayoutModes.Grid,
|
||||
isSortAscending: options.isSortAscending,
|
||||
},
|
||||
navIndex,
|
||||
};
|
||||
|
||||
return render(
|
||||
<TestProvider storeState={storeState}>
|
||||
<DataSourcesListPage />
|
||||
</TestProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
beforeEach(() => {
|
||||
(contextSrv.hasPermission as jest.Mock) = jest.fn().mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('should render component', async () => {
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'Data sources' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('link', { name: 'Add data source' })).toBeInTheDocument();
|
||||
|
||||
// Should not show button in page header when the list is empty
|
||||
expect(await screen.queryByRole('link', { name: 'Add new data source' })).toBeNull();
|
||||
});
|
||||
|
||||
describe('when user has no permissions', () => {
|
||||
beforeEach(() => {
|
||||
(contextSrv.hasPermission as jest.Mock) = jest.fn().mockReturnValue(false);
|
||||
});
|
||||
|
||||
it('should disable the "Add data source" button if user has no permissions', async () => {
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'Data sources' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('link', { name: 'Add data source' })).toHaveStyle('pointer-events: none');
|
||||
});
|
||||
|
||||
it('should not show the Explore button', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(3));
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findAllByRole('link', { name: /Build a dashboard/i })).toHaveLength(3);
|
||||
expect(screen.queryAllByRole('link', { name: 'Explore' })).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should not link cards to edit pages', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(1));
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
expect(await screen.queryByRole('link', { name: 'dataSource-0' })).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it('should show the Explore button', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(3));
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findAllByRole('link', { name: /Build a dashboard/i })).toHaveLength(3);
|
||||
expect(screen.queryAllByRole('link', { name: 'Explore' })).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('should link cards to edit pages', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(1));
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('link', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render action bar and datasources', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(5));
|
||||
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByPlaceholderText('Search by name or type')).toBeInTheDocument();
|
||||
expect(await screen.findByRole('combobox', { name: 'Sort' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-1' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-2' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-3' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-4' })).toBeInTheDocument();
|
||||
expect(await screen.findAllByRole('img')).toHaveLength(5);
|
||||
|
||||
// Should show button in page header when the list is not empty
|
||||
expect(await screen.findByRole('link', { name: 'Add new data source' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('should render elements in sort order', () => {
|
||||
it('ascending', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(5));
|
||||
setup({ isSortAscending: true });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
const dataSourceItems = await screen.findAllByRole('heading');
|
||||
|
||||
expect(dataSourceItems).toHaveLength(6);
|
||||
expect(dataSourceItems[0]).toHaveTextContent('Data sources');
|
||||
expect(dataSourceItems[1]).toHaveTextContent('dataSource-0');
|
||||
expect(dataSourceItems[2]).toHaveTextContent('dataSource-1');
|
||||
});
|
||||
it('descending', async () => {
|
||||
getDataSourcesMock.mockResolvedValue(getMockDataSources(5));
|
||||
setup({ isSortAscending: false });
|
||||
|
||||
expect(await screen.findByRole('heading', { name: 'dataSource-0' })).toBeInTheDocument();
|
||||
const dataSourceItems = await screen.findAllByRole('heading');
|
||||
|
||||
expect(dataSourceItems).toHaveLength(6);
|
||||
expect(dataSourceItems[0]).toHaveTextContent('Data sources');
|
||||
expect(dataSourceItems[1]).toHaveTextContent('dataSource-4');
|
||||
expect(dataSourceItems[2]).toHaveTextContent('dataSource-3');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { ConnectionsRedirectNotice } from 'app/features/connections/components/ConnectionsRedirectNotice';
|
||||
import { StoreState, useSelector } from 'app/types';
|
||||
|
||||
import { DataSourceAddButton } from '../components/DataSourceAddButton';
|
||||
import { DataSourcesList } from '../components/DataSourcesList';
|
||||
import { getDataSourcesCount } from '../state';
|
||||
|
||||
export function DataSourcesListPage() {
|
||||
const dataSourcesCount = useSelector(({ dataSources }: StoreState) => getDataSourcesCount(dataSources));
|
||||
|
||||
const actions = dataSourcesCount > 0 ? <DataSourceAddButton /> : undefined;
|
||||
return (
|
||||
<Page navId="datasources" actions={actions}>
|
||||
<Page.Contents>
|
||||
<ConnectionsRedirectNotice />
|
||||
<DataSourcesList />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default DataSourcesListPage;
|
||||
@@ -1,123 +0,0 @@
|
||||
import { screen, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { Store } from 'redux';
|
||||
import { TestProvider } from 'test/helpers/TestProvider';
|
||||
|
||||
import { LayoutModes } from '@grafana/data';
|
||||
import { setAngularLoader, setPluginExtensionGetter } from '@grafana/runtime';
|
||||
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
|
||||
import { navIndex, getMockDataSource, getMockDataSourceMeta, getMockDataSourceSettingsState } from '../__mocks__';
|
||||
import * as api from '../api';
|
||||
import { initialState } from '../state';
|
||||
|
||||
import { EditDataSourcePage } from './EditDataSourcePage';
|
||||
|
||||
jest.mock('../api');
|
||||
jest.mock('app/core/services/context_srv', () => ({
|
||||
contextSrv: {
|
||||
hasPermission: () => true,
|
||||
hasPermissionInMetadata: () => true,
|
||||
},
|
||||
}));
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
const original = jest.requireActual('@grafana/runtime');
|
||||
return {
|
||||
...original,
|
||||
getDataSourceSrv: jest.fn(() => ({
|
||||
getInstanceSettings: (uid: string) => ({
|
||||
uid,
|
||||
meta: getMockDataSourceMeta(),
|
||||
}),
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
const setup = (uid: string, store: Store) =>
|
||||
render(
|
||||
<TestProvider store={store}>
|
||||
<EditDataSourcePage
|
||||
{...getRouteComponentProps({
|
||||
// @ts-ignore
|
||||
match: {
|
||||
params: {
|
||||
uid,
|
||||
},
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</TestProvider>
|
||||
);
|
||||
|
||||
describe('<EditDataSourcePage>', () => {
|
||||
const uid = 'foo';
|
||||
const name = 'My DataSource';
|
||||
const dataSource = getMockDataSource<{}>({ uid, name });
|
||||
const dataSourceMeta = getMockDataSourceMeta();
|
||||
const dataSourceSettings = getMockDataSourceSettingsState();
|
||||
let store: Store;
|
||||
|
||||
beforeAll(() => {
|
||||
setAngularLoader({
|
||||
load: () => ({
|
||||
destroy: jest.fn(),
|
||||
digest: jest.fn(),
|
||||
getScope: () => ({ $watch: () => {} }),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
api.getDataSourceByIdOrUid = jest.fn().mockResolvedValue(dataSource);
|
||||
setPluginExtensionGetter(jest.fn().mockReturnValue({ extensions: [] }));
|
||||
|
||||
store = configureStore({
|
||||
dataSourceSettings,
|
||||
dataSources: {
|
||||
...initialState,
|
||||
dataSources: [dataSource],
|
||||
dataSource: dataSource,
|
||||
dataSourceMeta: dataSourceMeta,
|
||||
layoutMode: LayoutModes.Grid,
|
||||
isLoadingDataSources: false,
|
||||
},
|
||||
navIndex: {
|
||||
...navIndex,
|
||||
[`datasource-settings-${uid}`]: {
|
||||
id: `datasource-settings-${uid}`,
|
||||
text: name,
|
||||
icon: 'list-ul',
|
||||
url: `/datasources/edit/${uid}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the edit page without an issue', async () => {
|
||||
setup(uid, store);
|
||||
|
||||
expect(screen.queryByText('Loading ...')).not.toBeInTheDocument();
|
||||
|
||||
// Title
|
||||
expect(screen.queryByText(name)).toBeVisible();
|
||||
|
||||
// Buttons
|
||||
expect(screen.queryByRole('button', { name: /Save (.*) test/i })).toBeVisible();
|
||||
|
||||
// wait for the rest of the async processes to finish
|
||||
expect(await screen.findByText(name)).toBeVisible();
|
||||
});
|
||||
|
||||
it('should show updated action buttons when topnav is on', async () => {
|
||||
setup(uid, store);
|
||||
|
||||
await waitFor(() => {
|
||||
// Buttons
|
||||
expect(screen.queryByRole('button', { name: /Delete/i })).toBeVisible();
|
||||
expect(screen.queryByRole('link', { name: /Build a dashboard/i })).toBeVisible();
|
||||
expect(screen.queryAllByRole('link', { name: /Explore data/i })).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
|
||||
import DataSourceTabPage from '../components/DataSourceTabPage';
|
||||
import { EditDataSource } from '../components/EditDataSource';
|
||||
import { EditDataSourceActions } from '../components/EditDataSourceActions';
|
||||
import { useDataSourceSettingsNav } from '../state';
|
||||
|
||||
export interface Props extends GrafanaRouteComponentProps<{ uid: string }> {}
|
||||
|
||||
export function EditDataSourcePage(props: Props) {
|
||||
const uid = props.match.params.uid;
|
||||
const params = new URLSearchParams(props.location.search);
|
||||
const pageId = params.get('page');
|
||||
const dataSourcePageHeader = config.featureToggles.dataSourcePageHeader;
|
||||
const nav = useDataSourceSettingsNav(uid, pageId);
|
||||
|
||||
if (dataSourcePageHeader) {
|
||||
return <DataSourceTabPage uid={uid} pageId={pageId} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Page navId="datasources" pageNav={nav.main} actions={<EditDataSourceActions uid={uid} />}>
|
||||
<Page.Contents>
|
||||
<EditDataSource uid={uid} pageId={pageId} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditDataSourcePage;
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
|
||||
import { NewDataSource } from '../components/NewDataSource';
|
||||
import { DATASOURCES_ROUTES } from '../constants';
|
||||
|
||||
export function NewDataSourcePage() {
|
||||
const pageNav: NavModelItem = {
|
||||
icon: 'database',
|
||||
id: 'datasource-new',
|
||||
text: 'Add data source',
|
||||
url: DATASOURCES_ROUTES.New,
|
||||
subTitle: 'Choose a data source type',
|
||||
};
|
||||
|
||||
return (
|
||||
<Page navId="datasources" pageNav={pageNav}>
|
||||
<Page.Contents>
|
||||
<NewDataSource />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default NewDataSourcePage;
|
||||
@@ -1,12 +1,9 @@
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
import { DataSourcePluginMeta, DataSourceSettings, NavModel, NavModelItem } from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { DataSourcePluginMeta, DataSourceSettings } from '@grafana/data';
|
||||
import { cleanUpAction } from 'app/core/actions/cleanUp';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { useGetSingle } from 'app/features/plugins/admin/state/hooks';
|
||||
import { AccessControlAction, useDispatch, useSelector } from 'app/types';
|
||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||
|
||||
@@ -24,7 +21,6 @@ import {
|
||||
deleteLoadedDataSource,
|
||||
} from './actions';
|
||||
import { DataSourcesRoutesContext } from './contexts';
|
||||
import { getDataSourceLoadingNav, buildNavModel, getDataSourceNav } from './navModel';
|
||||
import { initialDataSourceSettingsState } from './reducers';
|
||||
import { getDataSource, getDataSourceMeta } from './selectors';
|
||||
|
||||
@@ -128,65 +124,6 @@ export const useDataSourceSettings = () => {
|
||||
return useSelector((state) => state.dataSourceSettings);
|
||||
};
|
||||
|
||||
export const useDataSourceSettingsNav = (dataSourceId: string, pageId: string | null) => {
|
||||
const { plugin, loadError, loading } = useDataSourceSettings();
|
||||
const dataSource = useDataSource(dataSourceId);
|
||||
const dsi = getDataSourceSrv()?.getInstanceSettings(dataSourceId);
|
||||
const hasAlertingEnabled = Boolean(dsi?.meta?.alerting ?? false);
|
||||
const isAlertManagerDatasource = dsi?.type === 'alertmanager';
|
||||
const alertingSupported = hasAlertingEnabled || isAlertManagerDatasource;
|
||||
|
||||
const datasourcePlugin = useGetSingle(dataSource.type);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
const navIndexId = pageId ? `datasource-${pageId}-${dataSourceId}` : `datasource-settings-${dataSourceId}`;
|
||||
let pageNav: NavModel = {
|
||||
node: {
|
||||
text: 'Data Source Nav Node',
|
||||
},
|
||||
main: {
|
||||
text: 'Data Source Nav Node',
|
||||
},
|
||||
};
|
||||
|
||||
if (loadError) {
|
||||
const node: NavModelItem = {
|
||||
text: loadError,
|
||||
subTitle: 'Data Source Error',
|
||||
icon: 'exclamation-triangle',
|
||||
};
|
||||
|
||||
pageNav = {
|
||||
node: node,
|
||||
main: node,
|
||||
};
|
||||
}
|
||||
|
||||
if (loading || !plugin) {
|
||||
pageNav = getNavModel(navIndex, navIndexId, getDataSourceLoadingNav('settings'));
|
||||
}
|
||||
|
||||
if (plugin) {
|
||||
pageNav = getNavModel(
|
||||
navIndex,
|
||||
navIndexId,
|
||||
getDataSourceNav(buildNavModel(dataSource, plugin), pageId || 'settings')
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
node: pageNav.node,
|
||||
main: {
|
||||
...pageNav.main,
|
||||
text: dataSource.name,
|
||||
dataSourcePluginName: datasourcePlugin?.name || plugin?.meta.name || '',
|
||||
active: true,
|
||||
},
|
||||
dataSourceHeader: {
|
||||
alertingSupported,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const useDataSourceRights = (uid: string): DataSourceRights => {
|
||||
const dataSource = useDataSource(uid);
|
||||
const readOnly = dataSource.readOnly === true;
|
||||
|
||||
Reference in New Issue
Block a user