Chore: InfluxDB - Reformatting and restructuring (#69669)

* Reformatting and restructuring

* Update unit test

* Export as function
This commit is contained in:
ismail simsek 2023-06-09 13:57:46 +03:00 committed by GitHub
parent 9f18e0ccf3
commit 3341229bc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 119 additions and 62 deletions

View File

@ -4144,9 +4144,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"] [0, 0, 0, "Do not use any type assertions.", "2"]
], ],
"public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/influxdb/datasource.ts:5381": [ "public/app/plugins/datasource/influxdb/datasource.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"],

View File

@ -8,7 +8,7 @@ const CHEAT_SHEET_ITEMS = [
}, },
]; ];
const InfluxCheatSheet = (props: any) => ( export const InfluxCheatSheet = () => (
<div> <div>
<h2>InfluxDB Cheat Sheet</h2> <h2>InfluxDB Cheat Sheet</h2>
{CHEAT_SHEET_ITEMS.map((item) => ( {CHEAT_SHEET_ITEMS.map((item) => (
@ -19,5 +19,3 @@ const InfluxCheatSheet = (props: any) => (
))} ))}
</div> </div>
); );
export default InfluxCheatSheet;

View File

@ -1,11 +1,7 @@
import React, { PureComponent } from 'react'; import React from 'react';
import { QueryEditorHelpProps } from '@grafana/data'; import { InfluxCheatSheet } from './InfluxCheatSheet';
import InfluxCheatSheet from './InfluxCheatSheet'; export function InfluxStartPage() {
return <InfluxCheatSheet />;
export default class InfluxStartPage extends PureComponent<QueryEditorHelpProps> {
render() {
return <InfluxCheatSheet onClickExample={this.props.onClickExample} />;
}
} }

View File

@ -4,7 +4,7 @@ import { HorizontalGroup, InlineFormLabel, Input, Select, TextArea } from '@graf
import { InfluxQuery } from '../../../../../types'; import { InfluxQuery } from '../../../../../types';
import { DEFAULT_RESULT_FORMAT, RESULT_FORMATS } from '../../../constants'; import { DEFAULT_RESULT_FORMAT, RESULT_FORMATS } from '../../../constants';
import { useShadowedState } from '../../hooks/useShadowedState'; import { useShadowedState } from '../hooks/useShadowedState';
type Props = { type Props = {
query: InfluxQuery; query: InfluxQuery;

View File

@ -0,0 +1,44 @@
import { renderHook } from '@testing-library/react-hooks';
import config from 'app/core/config';
import { getMockDS, getMockDSInstanceSettings, mockBackendService } from '../../../../../specs/mocks';
import { useRetentionPolicies } from './useRetentionPolicies';
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
}));
describe('useRetentionPolicies', () => {
it('should return all policies when influxdbBackendMigration feature toggle enabled', async () => {
const instanceSettings = getMockDSInstanceSettings();
const datasource = getMockDS(instanceSettings);
mockBackendService(response);
config.featureToggles.influxdbBackendMigration = true;
const { result, waitForNextUpdate } = renderHook(() => useRetentionPolicies(datasource));
await waitForNextUpdate();
expect(result.current.retentionPolicies.length).toEqual(4);
expect(result.current.retentionPolicies[0]).toEqual('autogen');
});
});
const response = {
data: {
results: {
metadataQuery: {
status: 200,
frames: [
{
schema: {
refId: 'metadataQuery',
fields: [{ name: 'value', type: 'string', typeInfo: { frame: 'string' } }],
},
data: { values: [['autogen', 'bar', '5m_avg', '1m_avg']] },
},
],
},
},
},
};

View File

@ -0,0 +1,15 @@
import { useEffect, useState } from 'react';
import InfluxDatasource from '../../../../../datasource';
import { getAllPolicies } from '../../../../../influxql_metadata_query';
export const useRetentionPolicies = (datasource: InfluxDatasource) => {
const [retentionPolicies, setRetentionPolicies] = useState<string[]>([]);
useEffect(() => {
getAllPolicies(datasource).then((data) => {
setRetentionPolicies(data);
});
}, [datasource]);
return { retentionPolicies };
};

View File

@ -0,0 +1,7 @@
// it is possible to add fields into the `InfluxQueryTag` structures, and they do work,
// but in some cases, when we do metadata queries, we have to remove them from the queries.
import { InfluxQueryTag } from '../../../../../types';
export function filterTags(parts: InfluxQueryTag[], allTagKeys: Set<string>): InfluxQueryTag[] {
return parts.filter((t) => t.key.endsWith('::tag') || allTagKeys.has(t.key + '::tag'));
}

View File

@ -0,0 +1,12 @@
import { TypedVariableModel } from '@grafana/data/src';
import { getTemplateSrv } from '@grafana/runtime/src';
export function getTemplateVariableOptions(wrapper: (v: TypedVariableModel) => string) {
return (
getTemplateSrv()
.getVariables()
// we make them regex-params, i'm not 100% sure why.
// probably because this way multi-value variables work ok too.
.map(wrapper)
);
}

View File

@ -0,0 +1,16 @@
// helper function to make it easy to call this from the widget-render-code
import { TypedVariableModel } from '@grafana/data/src';
import { getTemplateVariableOptions } from './getTemplateVariableOptions';
export function withTemplateVariableOptions(
optionsPromise: Promise<string[]>,
wrapper: (v: TypedVariableModel) => string,
filter?: string
): Promise<string[]> {
let templateVariableOptions = getTemplateVariableOptions(wrapper);
if (filter) {
templateVariableOptions = templateVariableOptions.filter((tvo) => tvo.indexOf(filter) > -1);
}
return optionsPromise.then((options) => [...templateVariableOptions, ...options]);
}

View File

@ -0,0 +1,9 @@
import { TypedVariableModel } from '@grafana/data/src';
export function wrapRegex(v: TypedVariableModel): string {
return `/^$${v.name}$/`;
}
export function wrapPure(v: TypedVariableModel): string {
return `$${v.name}`;
}

View File

@ -3,7 +3,7 @@ import React from 'react';
import { Input } from '@grafana/ui'; import { Input } from '@grafana/ui';
import { useShadowedState } from '../../hooks/useShadowedState'; import { useShadowedState } from '../hooks/useShadowedState';
import { paddingRightClass } from './styles'; import { paddingRightClass } from './styles';

View File

@ -6,7 +6,7 @@ import { useAsyncFn } from 'react-use';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { AsyncSelect, InlineLabel, Input, Select } from '@grafana/ui'; import { AsyncSelect, InlineLabel, Input, Select } from '@grafana/ui';
import { useShadowedState } from '../../hooks/useShadowedState'; import { useShadowedState } from '../hooks/useShadowedState';
// this file is a simpler version of `grafana-ui / SegmentAsync.tsx` // this file is a simpler version of `grafana-ui / SegmentAsync.tsx`
// with some changes: // with some changes:

View File

@ -1,9 +1,7 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { useId, useMemo } from 'react'; import React, { useId, useMemo } from 'react';
import { useAsync } from 'react-use';
import { GrafanaTheme2, TypedVariableModel } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { InlineLabel, SegmentSection, useStyles2 } from '@grafana/ui'; import { InlineLabel, SegmentSection, useStyles2 } from '@grafana/ui';
import InfluxDatasource from '../../../../../datasource'; import InfluxDatasource from '../../../../../datasource';
@ -25,7 +23,11 @@ import {
} from '../../../../../queryUtils'; } from '../../../../../queryUtils';
import { InfluxQuery, InfluxQueryTag } from '../../../../../types'; import { InfluxQuery, InfluxQueryTag } from '../../../../../types';
import { DEFAULT_RESULT_FORMAT } from '../../../constants'; import { DEFAULT_RESULT_FORMAT } from '../../../constants';
import { useRetentionPolicies } from '../hooks/useRetentionPolicies';
import { filterTags } from '../utils/filterTags';
import { getNewGroupByPartOptions, getNewSelectPartOptions, makePartList } from '../utils/partListUtils'; import { getNewGroupByPartOptions, getNewSelectPartOptions, makePartList } from '../utils/partListUtils';
import { withTemplateVariableOptions } from '../utils/withTemplateVariableOptions';
import { wrapPure, wrapRegex } from '../utils/wrapper';
import { FormatAsSection } from './FormatAsSection'; import { FormatAsSection } from './FormatAsSection';
import { FromSection } from './FromSection'; import { FromSection } from './FromSection';
@ -41,43 +43,6 @@ type Props = {
datasource: InfluxDatasource; datasource: InfluxDatasource;
}; };
function wrapRegex(v: TypedVariableModel): string {
return `/^$${v.name}$/`;
}
function wrapPure(v: TypedVariableModel): string {
return `$${v.name}`;
}
function getTemplateVariableOptions(wrapper: (v: TypedVariableModel) => string) {
return (
getTemplateSrv()
.getVariables()
// we make them regex-params, i'm not 100% sure why.
// probably because this way multi-value variables work ok too.
.map(wrapper)
);
}
// helper function to make it easy to call this from the widget-render-code
function withTemplateVariableOptions(
optionsPromise: Promise<string[]>,
wrapper: (v: TypedVariableModel) => string,
filter?: string
): Promise<string[]> {
let templateVariableOptions = getTemplateVariableOptions(wrapper);
if (filter) {
templateVariableOptions = templateVariableOptions.filter((tvo) => tvo.indexOf(filter) > -1);
}
return optionsPromise.then((options) => [...templateVariableOptions, ...options]);
}
// it is possible to add fields into the `InfluxQueryTag` structures, and they do work,
// but in some cases, when we do metadata queries, we have to remove them from the queries.
function filterTags(parts: InfluxQueryTag[], allTagKeys: Set<string>): InfluxQueryTag[] {
return parts.filter((t) => t.key.endsWith('::tag') || allTagKeys.has(t.key + '::tag'));
}
export const VisualInfluxQLEditor = (props: Props): JSX.Element => { export const VisualInfluxQLEditor = (props: Props): JSX.Element => {
const uniqueId = useId(); const uniqueId = useId();
const formatAsId = `influxdb-qe-format-as-${uniqueId}`; const formatAsId = `influxdb-qe-format-as-${uniqueId}`;
@ -87,9 +52,7 @@ export const VisualInfluxQLEditor = (props: Props): JSX.Element => {
const query = normalizeQuery(props.query); const query = normalizeQuery(props.query);
const { datasource } = props; const { datasource } = props;
const { measurement, policy } = query; const { measurement, policy } = query;
const { retentionPolicies } = useRetentionPolicies(datasource);
const policyData = useAsync(() => getAllPolicies(datasource), [datasource]);
const retentionPolicies = !!policyData.error ? [] : policyData.value ?? [];
const allTagKeys = useMemo(async () => { const allTagKeys = useMemo(async () => {
const tagKeys = (await getTagKeysForMeasurementAndTags(datasource, [], measurement, policy)).map( const tagKeys = (await getTagKeysForMeasurementAndTags(datasource, [], measurement, policy)).map(

View File

@ -2,7 +2,7 @@ import { DataSourcePlugin } from '@grafana/data';
import ConfigEditor from './components/editor/config/ConfigEditor'; import ConfigEditor from './components/editor/config/ConfigEditor';
import { QueryEditor } from './components/editor/query/QueryEditor'; import { QueryEditor } from './components/editor/query/QueryEditor';
import InfluxStartPage from './components/editor/query/influxql/InfluxStartPage'; import { InfluxStartPage } from './components/editor/query/influxql/InfluxStartPage';
import VariableQueryEditor from './components/editor/variable/VariableQueryEditor'; import VariableQueryEditor from './components/editor/variable/VariableQueryEditor';
import InfluxDatasource from './datasource'; import InfluxDatasource from './datasource';

View File

@ -58,6 +58,6 @@ export function getMockDSInstanceSettings(): DataSourceInstanceSettings<InfluxOp
module: '', module: '',
baseUrl: '', baseUrl: '',
}, },
jsonData: { version: InfluxVersion.InfluxQL, httpMode: 'POST' }, jsonData: { version: InfluxVersion.InfluxQL, httpMode: 'POST', dbName: 'site' },
}; };
} }