mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DataSourceSettings: use details from HealthCheckResult (#32759)
* add custom HealthCheckError * allow details from HealthCheckResult to be passed in the error * pass in details.message from testing status into Alert component * add chance * add aria label to read only message * update tests and add error message tests * extract HealthCheckResultDetails type out and add comment * extract TestingStatus interface out * remove chance from test * remove chance
This commit is contained in:
parent
fe67680c42
commit
59a33d98ec
@ -14,6 +14,7 @@ export const Pages = {
|
||||
DataSource: {
|
||||
name: 'Data source settings page name input field',
|
||||
delete: 'Data source settings page Delete button',
|
||||
readOnly: 'Data source settings page read only message',
|
||||
saveAndTest: 'Data source settings page Save and Test button',
|
||||
alert: 'Data source settings page Alert',
|
||||
},
|
||||
|
@ -15,6 +15,16 @@ import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse'
|
||||
|
||||
const ExpressionDatasourceID = '__expr__';
|
||||
|
||||
class HealthCheckError extends Error {
|
||||
details: HealthCheckResultDetails;
|
||||
|
||||
constructor(message: string, details: HealthCheckResultDetails) {
|
||||
super(message);
|
||||
this.details = details;
|
||||
this.name = 'HealthCheckError';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the current health status of a data source plugin.
|
||||
*
|
||||
@ -26,6 +36,16 @@ export enum HealthStatus {
|
||||
Error = 'ERROR',
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the details in the payload returned when checking the health of a data source
|
||||
* plugin.
|
||||
*
|
||||
* If the 'message' key exists, this will be displayed in the error message in DataSourceSettingsPage
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type HealthCheckResultDetails = Record<string, any> | undefined;
|
||||
|
||||
/**
|
||||
* Describes the payload returned when checking the health of a data source
|
||||
* plugin.
|
||||
@ -35,7 +55,7 @@ export enum HealthStatus {
|
||||
export interface HealthCheckResult {
|
||||
status: HealthStatus;
|
||||
message: string;
|
||||
details?: Record<string, any>;
|
||||
details: HealthCheckResultDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,7 +203,8 @@ class DataSourceWithBackend<
|
||||
message: res.message,
|
||||
};
|
||||
}
|
||||
throw new Error(res.message);
|
||||
|
||||
throw new HealthCheckError(res.message, res.details);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +1,142 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { DataSourceSettingsPage, Props } from './DataSourceSettingsPage';
|
||||
import { DataSourceConstructor, DataSourcePlugin, DataSourceSettings, NavModel } from '@grafana/data';
|
||||
import { getMockDataSource } from '../__mocks__/dataSourcesMocks';
|
||||
import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks';
|
||||
import { dataSourceLoaded, setDataSourceName, setIsDefault } from '../state/reducers';
|
||||
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
|
||||
import { cleanUpAction } from 'app/core/actions/cleanUp';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { PluginState } from '@grafana/data';
|
||||
|
||||
const pluginMock = new DataSourcePlugin({} as DataSourceConstructor<any>);
|
||||
|
||||
jest.mock('app/features/plugins/plugin_loader', () => {
|
||||
return {
|
||||
importDataSourcePlugin: () => Promise.resolve(pluginMock),
|
||||
};
|
||||
const getMockNode = () => ({
|
||||
text: 'text',
|
||||
subTitle: 'subtitle',
|
||||
icon: 'icon',
|
||||
});
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
...getRouteComponentProps(),
|
||||
navModel: {} as NavModel,
|
||||
dataSource: getMockDataSource(),
|
||||
dataSourceMeta: getMockPlugin(),
|
||||
dataSourceId: 1,
|
||||
deleteDataSource: jest.fn(),
|
||||
loadDataSource: jest.fn(),
|
||||
setDataSourceName,
|
||||
updateDataSource: jest.fn(),
|
||||
initDataSourceSettings: jest.fn(),
|
||||
testDataSource: jest.fn(),
|
||||
setIsDefault,
|
||||
dataSourceLoaded,
|
||||
cleanUpAction,
|
||||
page: null,
|
||||
plugin: null,
|
||||
loadError: null,
|
||||
testingStatus: {},
|
||||
...propOverrides,
|
||||
};
|
||||
|
||||
return shallow(<DataSourceSettingsPage {...props} />);
|
||||
};
|
||||
const getProps = (): Props => ({
|
||||
...getRouteComponentProps(),
|
||||
navModel: {
|
||||
node: getMockNode(),
|
||||
main: getMockNode(),
|
||||
},
|
||||
dataSource: getMockDataSource(),
|
||||
dataSourceMeta: getMockPlugin(),
|
||||
dataSourceId: 1,
|
||||
deleteDataSource: jest.fn(),
|
||||
loadDataSource: jest.fn(),
|
||||
setDataSourceName,
|
||||
updateDataSource: jest.fn(),
|
||||
initDataSourceSettings: jest.fn(),
|
||||
testDataSource: jest.fn(),
|
||||
setIsDefault,
|
||||
dataSourceLoaded,
|
||||
cleanUpAction,
|
||||
page: null,
|
||||
plugin: null,
|
||||
loadError: null,
|
||||
testingStatus: {},
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
it('should not render loading when props are ready', () => {
|
||||
render(<DataSourceSettingsPage {...getProps()} />);
|
||||
|
||||
expect(screen.queryByText('Loading ...')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render loader', () => {
|
||||
const wrapper = setup({
|
||||
dataSource: {} as DataSourceSettings,
|
||||
plugin: pluginMock,
|
||||
});
|
||||
it('should render loading if datasource is not ready', () => {
|
||||
const mockProps = getProps();
|
||||
mockProps.dataSource.id = 0;
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.getByText('Loading ...')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render beta info text', () => {
|
||||
const wrapper = setup({
|
||||
dataSourceMeta: { ...getMockPlugin(), state: 'beta' },
|
||||
});
|
||||
it('should render beta info text if plugin state is beta', () => {
|
||||
const mockProps = getProps();
|
||||
mockProps.dataSourceMeta.state = PluginState.beta;
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(
|
||||
screen.getByTitle('Beta Plugin: There could be bugs and minor breaking changes to this plugin')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render alpha info text', () => {
|
||||
const wrapper = setup({
|
||||
dataSourceMeta: { ...getMockPlugin(), state: 'alpha' },
|
||||
plugin: pluginMock,
|
||||
});
|
||||
it('should render alpha info text if plugin state is alpha', () => {
|
||||
const mockProps = getProps();
|
||||
mockProps.dataSourceMeta.state = PluginState.alpha;
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(
|
||||
screen.getByTitle('Alpha Plugin: This plugin is a work in progress and updates may include breaking changes')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render is ready only message', () => {
|
||||
const wrapper = setup({
|
||||
dataSource: { ...getMockDataSource(), readOnly: true },
|
||||
plugin: pluginMock,
|
||||
});
|
||||
it('should not render is ready only message is readOnly is false', () => {
|
||||
const mockProps = getProps();
|
||||
mockProps.dataSource.readOnly = false;
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.queryByLabelText(selectors.pages.DataSource.readOnly)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render is ready only message is readOnly is true', () => {
|
||||
const mockProps = getProps();
|
||||
mockProps.dataSource.readOnly = true;
|
||||
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.getByLabelText(selectors.pages.DataSource.readOnly)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render error message with detailed message', () => {
|
||||
const mockProps = {
|
||||
...getProps(),
|
||||
testingStatus: {
|
||||
message: 'message',
|
||||
status: 'error',
|
||||
details: { message: 'detailed message' },
|
||||
},
|
||||
};
|
||||
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.getByText(mockProps.testingStatus.message)).toBeInTheDocument();
|
||||
expect(screen.getByText(mockProps.testingStatus.details.message)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render error message with empty details', () => {
|
||||
const mockProps = {
|
||||
...getProps(),
|
||||
testingStatus: {
|
||||
message: 'message',
|
||||
status: 'error',
|
||||
details: {},
|
||||
},
|
||||
};
|
||||
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.getByText(mockProps.testingStatus.message)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render error message without details', () => {
|
||||
const mockProps = {
|
||||
...getProps(),
|
||||
testingStatus: {
|
||||
message: 'message',
|
||||
status: 'error',
|
||||
},
|
||||
};
|
||||
|
||||
render(<DataSourceSettingsPage {...mockProps} />);
|
||||
|
||||
expect(screen.getByText(mockProps.testingStatus.message)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -127,7 +127,7 @@ export class DataSourceSettingsPage extends PureComponent<Props> {
|
||||
|
||||
renderIsReadOnlyMessage() {
|
||||
return (
|
||||
<InfoBox severity="info">
|
||||
<InfoBox aria-label={selectors.pages.DataSource.readOnly} severity="info">
|
||||
This data source was added by config and cannot be modified using the UI. Please contact your server admin to
|
||||
update this data source.
|
||||
</InfoBox>
|
||||
@ -234,12 +234,14 @@ export class DataSourceSettingsPage extends PureComponent<Props> {
|
||||
)}
|
||||
|
||||
<div className="gf-form-group">
|
||||
{testingStatus && testingStatus.message && (
|
||||
{testingStatus?.message && (
|
||||
<Alert
|
||||
severity={testingStatus.status === 'error' ? 'error' : 'success'}
|
||||
title={testingStatus.message}
|
||||
aria-label={selectors.pages.DataSource.alert}
|
||||
/>
|
||||
>
|
||||
{testingStatus.details?.message ?? null}
|
||||
</Alert>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
@ -1,439 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render alpha info text 1`] = `
|
||||
<Page
|
||||
navModel={Object {}}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div>
|
||||
<form
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<label
|
||||
className="gf-form-label width-10"
|
||||
>
|
||||
Plugin state
|
||||
</label>
|
||||
<label
|
||||
className="gf-form-label gf-form-label--transparent"
|
||||
>
|
||||
<PluginStateinfo
|
||||
state="alpha"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<CloudInfoBox
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": false,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<BasicSettings
|
||||
dataSourceName="gdev-cloudwatch"
|
||||
isDefault={false}
|
||||
onDefaultChange={[Function]}
|
||||
onNameChange={[Function]}
|
||||
/>
|
||||
<PluginSettings
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": false,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
dataSourceMeta={
|
||||
Object {
|
||||
"baseUrl": "path/to/plugin",
|
||||
"defaultNavUrl": "some/url",
|
||||
"enabled": false,
|
||||
"hasUpdate": false,
|
||||
"id": "1",
|
||||
"info": Object {
|
||||
"author": Object {
|
||||
"name": "Grafana Labs",
|
||||
"url": "url/to/GrafanaLabs",
|
||||
},
|
||||
"description": "pretty decent plugin",
|
||||
"links": Array [
|
||||
Object {
|
||||
"name": "project",
|
||||
"url": "one link",
|
||||
},
|
||||
],
|
||||
"logos": Object {
|
||||
"large": "large/logo",
|
||||
"small": "small/logo",
|
||||
},
|
||||
"screenshots": Array [
|
||||
Object {
|
||||
"name": "test",
|
||||
"path": "screenshot",
|
||||
},
|
||||
],
|
||||
"updated": "2018-09-26",
|
||||
"version": "1",
|
||||
},
|
||||
"latestVersion": "1",
|
||||
"module": "path/to/module",
|
||||
"name": "pretty cool plugin 1",
|
||||
"pinned": false,
|
||||
"state": "alpha",
|
||||
"type": "panel",
|
||||
}
|
||||
}
|
||||
onModelChange={[Function]}
|
||||
plugin={
|
||||
DataSourcePlugin {
|
||||
"DataSourceClass": Object {},
|
||||
"components": Object {},
|
||||
"meta": Object {},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-group"
|
||||
/>
|
||||
<ButtonRow
|
||||
isReadOnly={false}
|
||||
onDelete={[Function]}
|
||||
onSubmit={[Function]}
|
||||
onTest={[Function]}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render should render beta info text 1`] = `
|
||||
<Page
|
||||
navModel={Object {}}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div>
|
||||
<form
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<label
|
||||
className="gf-form-label width-10"
|
||||
>
|
||||
Plugin state
|
||||
</label>
|
||||
<label
|
||||
className="gf-form-label gf-form-label--transparent"
|
||||
>
|
||||
<PluginStateinfo
|
||||
state="beta"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<CloudInfoBox
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": false,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<BasicSettings
|
||||
dataSourceName="gdev-cloudwatch"
|
||||
isDefault={false}
|
||||
onDefaultChange={[Function]}
|
||||
onNameChange={[Function]}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-group"
|
||||
/>
|
||||
<ButtonRow
|
||||
isReadOnly={false}
|
||||
onDelete={[Function]}
|
||||
onSubmit={[Function]}
|
||||
onTest={[Function]}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<Page
|
||||
navModel={Object {}}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div>
|
||||
<form
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<CloudInfoBox
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": false,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<BasicSettings
|
||||
dataSourceName="gdev-cloudwatch"
|
||||
isDefault={false}
|
||||
onDefaultChange={[Function]}
|
||||
onNameChange={[Function]}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-group"
|
||||
/>
|
||||
<ButtonRow
|
||||
isReadOnly={false}
|
||||
onDelete={[Function]}
|
||||
onSubmit={[Function]}
|
||||
onTest={[Function]}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render should render is ready only message 1`] = `
|
||||
<Page
|
||||
navModel={Object {}}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div>
|
||||
<form
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<InfoBox
|
||||
severity="info"
|
||||
>
|
||||
This data source was added by config and cannot be modified using the UI. Please contact your server admin to update this data source.
|
||||
</InfoBox>
|
||||
<CloudInfoBox
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": true,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<BasicSettings
|
||||
dataSourceName="gdev-cloudwatch"
|
||||
isDefault={false}
|
||||
onDefaultChange={[Function]}
|
||||
onNameChange={[Function]}
|
||||
/>
|
||||
<PluginSettings
|
||||
dataSource={
|
||||
Object {
|
||||
"access": "",
|
||||
"basicAuth": false,
|
||||
"basicAuthPassword": "",
|
||||
"basicAuthUser": "",
|
||||
"database": "",
|
||||
"id": 13,
|
||||
"isDefault": false,
|
||||
"jsonData": Object {
|
||||
"authType": "credentials",
|
||||
"defaultRegion": "eu-west-2",
|
||||
},
|
||||
"name": "gdev-cloudwatch",
|
||||
"orgId": 1,
|
||||
"password": "",
|
||||
"readOnly": true,
|
||||
"secureJsonFields": Object {},
|
||||
"type": "cloudwatch",
|
||||
"typeLogoUrl": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
"typeName": "Cloudwatch",
|
||||
"url": "",
|
||||
"user": "",
|
||||
"withCredentials": false,
|
||||
}
|
||||
}
|
||||
dataSourceMeta={
|
||||
Object {
|
||||
"baseUrl": "path/to/plugin",
|
||||
"defaultNavUrl": "some/url",
|
||||
"enabled": false,
|
||||
"hasUpdate": false,
|
||||
"id": "1",
|
||||
"info": Object {
|
||||
"author": Object {
|
||||
"name": "Grafana Labs",
|
||||
"url": "url/to/GrafanaLabs",
|
||||
},
|
||||
"description": "pretty decent plugin",
|
||||
"links": Array [
|
||||
Object {
|
||||
"name": "project",
|
||||
"url": "one link",
|
||||
},
|
||||
],
|
||||
"logos": Object {
|
||||
"large": "large/logo",
|
||||
"small": "small/logo",
|
||||
},
|
||||
"screenshots": Array [
|
||||
Object {
|
||||
"name": "test",
|
||||
"path": "screenshot",
|
||||
},
|
||||
],
|
||||
"updated": "2018-09-26",
|
||||
"version": "1",
|
||||
},
|
||||
"latestVersion": "1",
|
||||
"module": "path/to/module",
|
||||
"name": "pretty cool plugin 1",
|
||||
"pinned": false,
|
||||
"type": "panel",
|
||||
}
|
||||
}
|
||||
onModelChange={[Function]}
|
||||
plugin={
|
||||
DataSourcePlugin {
|
||||
"DataSourceClass": Object {},
|
||||
"components": Object {},
|
||||
"meta": Object {},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-group"
|
||||
/>
|
||||
<ButtonRow
|
||||
isReadOnly={true}
|
||||
onDelete={[Function]}
|
||||
onSubmit={[Function]}
|
||||
onTest={[Function]}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render should render loader 1`] = `
|
||||
<Page
|
||||
navModel={Object {}}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={true}
|
||||
/>
|
||||
</Page>
|
||||
`;
|
@ -95,15 +95,10 @@ export const testDataSource = (
|
||||
|
||||
dispatch(testDataSourceSucceeded(result));
|
||||
} catch (err) {
|
||||
let message = '';
|
||||
const { statusText, message: errMessage, details } = err;
|
||||
const message = statusText ? 'HTTP error ' + statusText : errMessage;
|
||||
|
||||
if (err.statusText) {
|
||||
message = 'HTTP error ' + err.statusText;
|
||||
} else {
|
||||
message = err.message;
|
||||
}
|
||||
|
||||
dispatch(testDataSourceFailed({ message }));
|
||||
dispatch(testDataSourceFailed({ message, details }));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { AnyAction, createAction } from '@reduxjs/toolkit';
|
||||
import { DataSourcePluginMeta, DataSourceSettings } from '@grafana/data';
|
||||
|
||||
import { DataSourcesState, DataSourceSettingsState } from 'app/types';
|
||||
import { DataSourcesState, DataSourceSettingsState, TestingStatus } from 'app/types';
|
||||
import { LayoutMode, LayoutModes } from 'app/core/components/LayoutSelector/LayoutSelector';
|
||||
import { DataSourceTypesLoadedPayload } from './actions';
|
||||
import { GenericDataSourcePlugin } from '../settings/PluginSettings';
|
||||
@ -96,10 +96,7 @@ export const dataSourcesReducer = (state: DataSourcesState = initialState, actio
|
||||
};
|
||||
|
||||
export const initialDataSourceSettingsState: DataSourceSettingsState = {
|
||||
testingStatus: {
|
||||
status: null,
|
||||
message: null,
|
||||
},
|
||||
testingStatus: {},
|
||||
loadError: null,
|
||||
plugin: null,
|
||||
};
|
||||
@ -112,12 +109,9 @@ export const initDataSourceSettingsFailed = createAction<Error>('dataSourceSetti
|
||||
|
||||
export const testDataSourceStarting = createAction<undefined>('dataSourceSettings/testDataSourceStarting');
|
||||
|
||||
export const testDataSourceSucceeded = createAction<{
|
||||
status: string;
|
||||
message: string;
|
||||
}>('dataSourceSettings/testDataSourceSucceeded');
|
||||
export const testDataSourceSucceeded = createAction<TestingStatus>('dataSourceSettings/testDataSourceSucceeded');
|
||||
|
||||
export const testDataSourceFailed = createAction<{ message: string }>('dataSourceSettings/testDataSourceFailed');
|
||||
export const testDataSourceFailed = createAction<TestingStatus>('dataSourceSettings/testDataSourceFailed');
|
||||
|
||||
export const dataSourceSettingsReducer = (
|
||||
state: DataSourceSettingsState = initialDataSourceSettingsState,
|
||||
@ -145,8 +139,9 @@ export const dataSourceSettingsReducer = (
|
||||
return {
|
||||
...state,
|
||||
testingStatus: {
|
||||
status: action.payload.status,
|
||||
message: action.payload.message,
|
||||
status: action.payload?.status,
|
||||
message: action.payload?.message,
|
||||
details: action.payload?.details,
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -156,7 +151,8 @@ export const dataSourceSettingsReducer = (
|
||||
...state,
|
||||
testingStatus: {
|
||||
status: 'error',
|
||||
message: action.payload.message,
|
||||
message: action.payload?.message,
|
||||
details: action.payload?.details,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector';
|
||||
import { DataSourcePluginMeta, DataSourceSettings } from '@grafana/data';
|
||||
import { GenericDataSourcePlugin } from 'app/features/datasources/settings/PluginSettings';
|
||||
import { HealthCheckResultDetails } from '@grafana/runtime/src/utils/DataSourceWithBackend';
|
||||
|
||||
export interface DataSourcesState {
|
||||
dataSources: DataSourceSettings[];
|
||||
@ -16,12 +17,15 @@ export interface DataSourcesState {
|
||||
categories: DataSourcePluginCategory[];
|
||||
}
|
||||
|
||||
export interface TestingStatus {
|
||||
message?: string | null;
|
||||
status?: string | null;
|
||||
details?: HealthCheckResultDetails;
|
||||
}
|
||||
|
||||
export interface DataSourceSettingsState {
|
||||
plugin?: GenericDataSourcePlugin | null;
|
||||
testingStatus?: {
|
||||
message?: string | null;
|
||||
status?: string | null;
|
||||
};
|
||||
testingStatus?: TestingStatus;
|
||||
loadError?: string | null;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user