restore basicSettings component and apply feature toggle
This commit is contained in:
@@ -2593,6 +2593,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "11"]
|
||||
],
|
||||
"public/app/features/datasources/components/BasicSettings.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/features/datasources/components/DataSourceReadOnlyMessage.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
useDataSource,
|
||||
useDataSourceSettingsNav as useDataSourceSettingsNavOriginal,
|
||||
} from 'app/features/datasources/state/hooks';
|
||||
import { useGetSingle } from 'app/features/plugins/admin/state/hooks';
|
||||
|
||||
// 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) {
|
||||
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,
|
||||
text: datasource.name,
|
||||
subTitle: `Type: ${datasourcePlugin?.name}`,
|
||||
active: true,
|
||||
children: (nav.main.children || []).map((navModelItem) => ({
|
||||
...navModelItem,
|
||||
url: navModelItem.url?.replace('datasources/edit/', '/connections/datasources/edit/'),
|
||||
})),
|
||||
};
|
||||
|
||||
return {
|
||||
navId: 'connections-datasources',
|
||||
pageNav,
|
||||
};
|
||||
}
|
||||
@@ -1,13 +1,31 @@
|
||||
import * as React from 'react';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import DataSourceTabPage from 'app/features/datasources/components/DataSourceTabPage';
|
||||
import { EditDataSource } from 'app/features/datasources/components/EditDataSource';
|
||||
import { EditDataSourceActions } from 'app/features/datasources/components/EditDataSourceActions';
|
||||
|
||||
import { useDataSourceSettingsNav } from '../hooks/useDataSourceSettingsNav';
|
||||
|
||||
export function EditDataSourcePage() {
|
||||
const { uid } = useParams<{ uid: string }>();
|
||||
const location = useLocation();
|
||||
const params = new URLSearchParams(location.search);
|
||||
const pageId = params.get('page');
|
||||
const dataSourcePageHeader = config.featureToggles.dataSourcePageHeader;
|
||||
const { navId, pageNav } = useDataSourceSettingsNav();
|
||||
|
||||
return <DataSourceTabPage uid={uid} pageId={pageId} navId="connections-datasources" />;
|
||||
if (dataSourcePageHeader) {
|
||||
return <DataSourceTabPage uid={uid} pageId={pageId} navId="connections-datasources" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Page navId={navId} pageNav={pageNav} actions={<EditDataSourceActions uid={uid} />}>
|
||||
<Page.Contents>
|
||||
<EditDataSource uid={uid} pageId={pageId} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { BasicSettings, Props } from './BasicSettings';
|
||||
|
||||
const setup = () => {
|
||||
const props: Props = {
|
||||
dataSourceName: 'Graphite',
|
||||
isDefault: false,
|
||||
onDefaultChange: jest.fn(),
|
||||
onNameChange: jest.fn(),
|
||||
alertingSupported: false,
|
||||
};
|
||||
|
||||
return render(<BasicSettings {...props} />);
|
||||
};
|
||||
|
||||
describe('<BasicSettings>', () => {
|
||||
it('should render component', () => {
|
||||
setup();
|
||||
|
||||
expect(screen.getByRole('textbox', { name: selectors.pages.DataSource.name })).toBeInTheDocument();
|
||||
expect(screen.getByRole('checkbox', { name: /Default/ })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { InlineField, InlineSwitch, Input, Badge, useStyles2 } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
dataSourceName: string;
|
||||
isDefault: boolean;
|
||||
onNameChange: (name: string) => void;
|
||||
onDefaultChange: (value: boolean) => void;
|
||||
alertingSupported: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export function BasicSettings({
|
||||
dataSourceName,
|
||||
isDefault,
|
||||
onDefaultChange,
|
||||
onNameChange,
|
||||
alertingSupported,
|
||||
disabled,
|
||||
}: Props) {
|
||||
return (
|
||||
<>
|
||||
<AlertingEnabled enabled={alertingSupported} />
|
||||
|
||||
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
|
||||
<div className="gf-form-inline">
|
||||
{/* Name */}
|
||||
<div className="gf-form max-width-30">
|
||||
<InlineField
|
||||
label="Name"
|
||||
tooltip="The name is used when you select the data source in panels. The default data source is
|
||||
'preselected in new panels."
|
||||
grow
|
||||
disabled={disabled}
|
||||
>
|
||||
<Input
|
||||
id="basic-settings-name"
|
||||
type="text"
|
||||
value={dataSourceName}
|
||||
placeholder="Name"
|
||||
onChange={(event) => onNameChange(event.currentTarget.value)}
|
||||
required
|
||||
aria-label={selectors.pages.DataSource.name}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
|
||||
{/* Is Default */}
|
||||
<InlineField label="Default" labelWidth={8} disabled={disabled}>
|
||||
<InlineSwitch
|
||||
id="basic-settings-default"
|
||||
value={isDefault}
|
||||
onChange={(event: React.FormEvent<HTMLInputElement>) => {
|
||||
onDefaultChange(event.currentTarget.checked);
|
||||
}}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function AlertingEnabled({ enabled }: { enabled: boolean }) {
|
||||
const styles = useStyles2(getStyles);
|
||||
return (
|
||||
<div className={styles.badge}>
|
||||
{enabled ? (
|
||||
<Badge color="green" icon="check-circle" text="Alerting supported" />
|
||||
) : (
|
||||
<Badge color="orange" icon="exclamation-triangle" text="Alerting not supported" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
badge: css`
|
||||
margin-bottom: ${theme.spacing(2)};
|
||||
`,
|
||||
});
|
||||
@@ -37,6 +37,8 @@ const setup = (props?: Partial<ViewProps>) => {
|
||||
dataSourceRights={{ readOnly: false, hasWriteRights: true, hasDeleteRights: true }}
|
||||
exploreUrl={'/explore'}
|
||||
onDelete={jest.fn()}
|
||||
onDefaultChange={jest.fn()}
|
||||
onNameChange={jest.fn()}
|
||||
onOptionsChange={jest.fn()}
|
||||
onTest={jest.fn()}
|
||||
onUpdate={jest.fn()}
|
||||
|
||||
@@ -6,12 +6,14 @@ import {
|
||||
DataSourcePluginMeta,
|
||||
DataSourceSettings as DataSourceSettingsType,
|
||||
} from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { getDataSourceSrv, config } from '@grafana/runtime';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { DataSourceSettingsState, useDispatch } from 'app/types';
|
||||
|
||||
import {
|
||||
dataSourceLoaded,
|
||||
setDataSourceName,
|
||||
setIsDefault,
|
||||
useDataSource,
|
||||
useDataSourceExploreUrl,
|
||||
useDataSourceMeta,
|
||||
@@ -24,6 +26,7 @@ import {
|
||||
} from '../state';
|
||||
import { DataSourceRights } from '../types';
|
||||
|
||||
import { BasicSettings } from './BasicSettings';
|
||||
import { ButtonRow } from './ButtonRow';
|
||||
import { CloudInfoBox } from './CloudInfoBox';
|
||||
import { DataSourceLoadError } from './DataSourceLoadError';
|
||||
@@ -53,6 +56,8 @@ export function EditDataSource({ uid, pageId }: Props) {
|
||||
const onDelete = useDeleteLoadedDataSource();
|
||||
const onTest = useTestDataSource(uid);
|
||||
const onUpdate = useUpdateDatasource();
|
||||
const onDefaultChange = (value: boolean) => dispatch(setIsDefault(value));
|
||||
const onNameChange = (name: string) => dispatch(setDataSourceName(name));
|
||||
const onOptionsChange = (ds: DataSourceSettingsType) => dispatch(dataSourceLoaded(ds));
|
||||
|
||||
return (
|
||||
@@ -64,6 +69,8 @@ export function EditDataSource({ uid, pageId }: Props) {
|
||||
dataSourceRights={dataSourceRights}
|
||||
exploreUrl={exploreUrl}
|
||||
onDelete={onDelete}
|
||||
onDefaultChange={onDefaultChange}
|
||||
onNameChange={onNameChange}
|
||||
onOptionsChange={onOptionsChange}
|
||||
onTest={onTest}
|
||||
onUpdate={onUpdate}
|
||||
@@ -79,6 +86,8 @@ export type ViewProps = {
|
||||
dataSourceRights: DataSourceRights;
|
||||
exploreUrl: string;
|
||||
onDelete: () => void;
|
||||
onDefaultChange: (isDefault: boolean) => AnyAction;
|
||||
onNameChange: (name: string) => AnyAction;
|
||||
onOptionsChange: (dataSource: DataSourceSettingsType) => AnyAction;
|
||||
onTest: () => void;
|
||||
onUpdate: (dataSource: DataSourceSettingsType) => Promise<DataSourceSettingsType>;
|
||||
@@ -92,6 +101,8 @@ export function EditDataSourceView({
|
||||
dataSourceRights,
|
||||
exploreUrl,
|
||||
onDelete,
|
||||
onDefaultChange,
|
||||
onNameChange,
|
||||
onOptionsChange,
|
||||
onTest,
|
||||
onUpdate,
|
||||
@@ -102,6 +113,11 @@ export function EditDataSourceView({
|
||||
|
||||
const dsi = getDataSourceSrv()?.getInstanceSettings(dataSource.uid);
|
||||
|
||||
const hasAlertingEnabled = Boolean(dsi?.meta?.alerting ?? false);
|
||||
const isAlertManagerDatasource = dsi?.type === 'alertmanager';
|
||||
const alertingSupported = hasAlertingEnabled || isAlertManagerDatasource;
|
||||
const dataSourcePageHeader = config.featureToggles.dataSourcePageHeader;
|
||||
|
||||
const onSubmit = async (e: React.MouseEvent<HTMLButtonElement> | React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
@@ -142,6 +158,17 @@ export function EditDataSourceView({
|
||||
|
||||
<CloudInfoBox dataSource={dataSource} />
|
||||
|
||||
{!dataSourcePageHeader && (
|
||||
<BasicSettings
|
||||
dataSourceName={dataSource.name}
|
||||
isDefault={dataSource.isDefault}
|
||||
onDefaultChange={onDefaultChange}
|
||||
onNameChange={onNameChange}
|
||||
alertingSupported={alertingSupported}
|
||||
disabled={readOnly || !hasWriteRights}
|
||||
/>
|
||||
)}
|
||||
|
||||
{plugin && (
|
||||
<DataSourcePluginContextProvider instanceSettings={dsi}>
|
||||
<DataSourcePluginSettings
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
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 }> {}
|
||||
|
||||
@@ -10,8 +15,20 @@ 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);
|
||||
|
||||
return <DataSourceTabPage uid={uid} pageId={pageId} navId="datasources" />;
|
||||
if (dataSourcePageHeader) {
|
||||
return <DataSourceTabPage uid={uid} pageId={pageId} navId="datasources" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Page navId="datasources" pageNav={nav.main} actions={<EditDataSourceActions uid={uid} />}>
|
||||
<Page.Contents>
|
||||
<EditDataSource uid={uid} pageId={pageId} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditDataSourcePage;
|
||||
|
||||
Reference in New Issue
Block a user