mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudMonitoring: Fix fastpass issues (#44277)
This commit is contained in:
parent
de2c5783fa
commit
af0ece12f9
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useTheme2 } from '../../themes';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
import { getSelectStyles } from './getSelectStyles';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
interface MultiValueContainerProps {
|
||||
innerProps: any;
|
||||
@ -25,9 +26,5 @@ export type MultiValueRemoveProps = {
|
||||
export const MultiValueRemove: React.FC<MultiValueRemoveProps> = ({ children, innerProps }) => {
|
||||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
return (
|
||||
<div {...innerProps} className={styles.multiValueRemove}>
|
||||
<Icon name="times" size="sm" />
|
||||
</div>
|
||||
);
|
||||
return <IconButton {...innerProps} name="times" size="sm" className={styles.multiValueRemove} />;
|
||||
};
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React, { FC, useMemo } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import React, { FC, useMemo } from 'react';
|
||||
|
||||
import { QueryEditorField } from '.';
|
||||
import { getAggregationOptionsByMetric } from '../functions';
|
||||
import { MetricDescriptor, ValueTypes, MetricKind } from '../types';
|
||||
import { MetricDescriptor, MetricKind, ValueTypes } from '../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (metricDescriptor: string) => void;
|
||||
metricDescriptor?: MetricDescriptor;
|
||||
crossSeriesReducer: string;
|
||||
@ -19,7 +20,12 @@ export const Aggregation: FC<Props> = (props) => {
|
||||
const selected = useSelectedFromOptions(aggOptions, props);
|
||||
|
||||
return (
|
||||
<QueryEditorField labelWidth={18} label="Group by function" data-testid="cloud-monitoring-aggregation">
|
||||
<QueryEditorField
|
||||
labelWidth={18}
|
||||
label="Group by function"
|
||||
data-testid="cloud-monitoring-aggregation"
|
||||
htmlFor={`${props.refId}-group-by-function`}
|
||||
>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
width={16}
|
||||
@ -37,6 +43,7 @@ export const Aggregation: FC<Props> = (props) => {
|
||||
},
|
||||
]}
|
||||
placeholder="Select Reducer"
|
||||
inputId={`${props.refId}-group-by-function`}
|
||||
/>
|
||||
</QueryEditorField>
|
||||
);
|
||||
|
@ -1,15 +1,17 @@
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { debounce } from 'lodash';
|
||||
import { Input } from '@grafana/ui';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
|
||||
import { QueryEditorRow } from '.';
|
||||
import { INPUT_WIDTH } from '../constants';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (alias: any) => void;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const AliasBy: FunctionComponent<Props> = ({ value = '', onChange }) => {
|
||||
export const AliasBy: FunctionComponent<Props> = ({ refId, value = '', onChange }) => {
|
||||
const [alias, setAlias] = useState(value ?? '');
|
||||
|
||||
const propagateOnChange = debounce(onChange, 1000);
|
||||
@ -20,8 +22,8 @@ export const AliasBy: FunctionComponent<Props> = ({ value = '', onChange }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="Alias by">
|
||||
<Input width={INPUT_WIDTH} value={alias} onChange={onChange} />
|
||||
<QueryEditorRow label="Alias by" htmlFor={`${refId}-alias-by`}>
|
||||
<Input id={`${refId}-alias-by`} width={INPUT_WIDTH} value={alias} onChange={onChange} />
|
||||
</QueryEditorRow>
|
||||
);
|
||||
};
|
||||
|
@ -1,11 +1,13 @@
|
||||
import React, { FC } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import { CustomMetaData, MetricQuery, SLOQuery } from '../types';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import { AlignmentFunction, AlignmentPeriod, AlignmentPeriodLabel, QueryEditorField, QueryEditorRow } from '.';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { CustomMetaData, MetricQuery, SLOQuery } from '../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: MetricQuery | SLOQuery) => void;
|
||||
query: MetricQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
@ -13,16 +15,30 @@ export interface Props {
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const Alignment: FC<Props> = ({ templateVariableOptions, onChange, query, customMetaData, datasource }) => {
|
||||
export const Alignment: FC<Props> = ({
|
||||
refId,
|
||||
templateVariableOptions,
|
||||
onChange,
|
||||
query,
|
||||
customMetaData,
|
||||
datasource,
|
||||
}) => {
|
||||
return (
|
||||
<QueryEditorRow
|
||||
label="Alignment function"
|
||||
tooltip="The process of alignment consists of collecting all data points received in a fixed length of time, applying a function to combine those data points, and assigning a timestamp to the result."
|
||||
fillComponent={<AlignmentPeriodLabel datasource={datasource} customMetaData={customMetaData} />}
|
||||
htmlFor={`${refId}-alignment-function`}
|
||||
>
|
||||
<AlignmentFunction templateVariableOptions={templateVariableOptions} query={query} onChange={onChange} />
|
||||
<QueryEditorField label="Alignment period">
|
||||
<AlignmentFunction
|
||||
inputId={`${refId}-alignment-function`}
|
||||
templateVariableOptions={templateVariableOptions}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<QueryEditorField label="Alignment period" htmlFor={`${refId}-alignment-period`}>
|
||||
<AlignmentPeriod
|
||||
inputId={`${refId}-alignment-period`}
|
||||
selectWidth={SELECT_WIDTH}
|
||||
templateVariableOptions={templateVariableOptions}
|
||||
query={query}
|
||||
|
@ -1,17 +1,19 @@
|
||||
import React, { FC, useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import { MetricQuery } from '../types';
|
||||
import { getAlignmentPickerData } from '../functions';
|
||||
import React, { FC, useMemo } from 'react';
|
||||
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import { getAlignmentPickerData } from '../functions';
|
||||
import { MetricQuery } from '../types';
|
||||
|
||||
export interface Props {
|
||||
inputId: string;
|
||||
onChange: (query: MetricQuery) => void;
|
||||
query: MetricQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
}
|
||||
|
||||
export const AlignmentFunction: FC<Props> = ({ query, templateVariableOptions, onChange }) => {
|
||||
export const AlignmentFunction: FC<Props> = ({ inputId, query, templateVariableOptions, onChange }) => {
|
||||
const { valueType, metricKind, perSeriesAligner: psa, preprocessor } = query;
|
||||
const { perSeriesAligner, alignOptions } = useMemo(
|
||||
() => getAlignmentPickerData(valueType, metricKind, psa, preprocessor),
|
||||
@ -36,6 +38,7 @@ export const AlignmentFunction: FC<Props> = ({ query, templateVariableOptions, o
|
||||
},
|
||||
]}
|
||||
placeholder="Select Alignment"
|
||||
inputId={inputId}
|
||||
></Select>
|
||||
);
|
||||
};
|
||||
|
@ -1,10 +1,12 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { ALIGNMENT_PERIODS } from '../constants';
|
||||
import { MetricQuery, SLOQuery } from '../types';
|
||||
|
||||
export interface Props<TQuery> {
|
||||
inputId: string;
|
||||
onChange(query: TQuery): void;
|
||||
query: TQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
@ -12,6 +14,7 @@ export interface Props<TQuery> {
|
||||
}
|
||||
|
||||
export function AlignmentPeriod<TQuery extends MetricQuery | SLOQuery>({
|
||||
inputId,
|
||||
templateVariableOptions,
|
||||
onChange,
|
||||
query,
|
||||
@ -45,6 +48,7 @@ export function AlignmentPeriod<TQuery extends MetricQuery | SLOQuery>({
|
||||
},
|
||||
]}
|
||||
placeholder="Select Alignment"
|
||||
inputId={inputId}
|
||||
></Select>
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
import React from 'react';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
import { SelectableValue, toOption } from '@grafana/data';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import React from 'react';
|
||||
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { AnnotationsHelp, LabelFilter, Metrics, Project, QueryEditorRow } from './';
|
||||
import { AnnotationTarget, EditorMode, MetricDescriptor, MetricKind } from '../types';
|
||||
import { AnnotationsHelp, LabelFilter, Metrics, Project, QueryEditorRow } from './';
|
||||
|
||||
const { Input } = LegacyForms;
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onQueryChange: (target: AnnotationTarget) => void;
|
||||
target: AnnotationTarget;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
@ -97,12 +98,14 @@ export class AnnotationQueryEditor extends React.Component<Props, State> {
|
||||
return (
|
||||
<>
|
||||
<Project
|
||||
refId={this.props.refId}
|
||||
templateVariableOptions={variableOptions}
|
||||
datasource={datasource}
|
||||
projectName={projectName || datasource.getDefaultProject()}
|
||||
onChange={(value) => this.onChange('projectName', value)}
|
||||
/>
|
||||
<Metrics
|
||||
refId={this.props.refId}
|
||||
projectName={projectName}
|
||||
metricType={metricType}
|
||||
templateSrv={datasource.templateSrv}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Select, InlineField, Alert } from '@grafana/ui';
|
||||
import { DataSourcePluginOptionsEditorProps, onUpdateDatasourceJsonDataOptionSelect } from '@grafana/data';
|
||||
import { Alert, InlineField, Select } from '@grafana/ui';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { AuthType, authTypes, CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../types';
|
||||
import { JWTConfig } from './JWTConfig';
|
||||
|
||||
@ -19,8 +20,9 @@ export class ConfigEditor extends PureComponent<Props> {
|
||||
<>
|
||||
<h3 className="page-heading">Authentication</h3>
|
||||
<div>
|
||||
<InlineField label="Type" labelWidth={20}>
|
||||
<InlineField label="Type" labelWidth={20} htmlFor="cloud-monitoring-type">
|
||||
<Select
|
||||
inputId="cloud-monitoring-type"
|
||||
menuShouldPortal
|
||||
width={40}
|
||||
value={authTypes.find((x) => x.value === jsonData.authenticationType) || authTypes[0]}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { FC } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { HorizontalGroup, InlineLabel, PopoverContent, Select, InlineField } from '@grafana/ui';
|
||||
import { css } from '@emotion/css';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { HorizontalGroup, InlineField, InlineLabel, PopoverContent, Select } from '@grafana/ui';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import { INNER_LABEL_WIDTH, LABEL_WIDTH } from '../constants';
|
||||
|
||||
interface VariableQueryFieldProps {
|
||||
@ -41,6 +42,7 @@ export interface Props {
|
||||
noFillEnd?: boolean;
|
||||
labelWidth?: number;
|
||||
fillComponent?: React.ReactNode;
|
||||
htmlFor?: string;
|
||||
}
|
||||
|
||||
export const QueryEditorRow: FC<Props> = ({
|
||||
@ -50,12 +52,13 @@ export const QueryEditorRow: FC<Props> = ({
|
||||
fillComponent,
|
||||
noFillEnd = false,
|
||||
labelWidth = LABEL_WIDTH,
|
||||
htmlFor,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
<div className="gf-form" {...rest}>
|
||||
{label && (
|
||||
<InlineLabel width={labelWidth} tooltip={tooltip}>
|
||||
<InlineLabel width={labelWidth} tooltip={tooltip} htmlFor={htmlFor}>
|
||||
{label}
|
||||
</InlineLabel>
|
||||
)}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import React, { FunctionComponent, useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { MultiSelect } from '@grafana/ui';
|
||||
import { labelsToGroupedOptions } from '../functions';
|
||||
import { SYSTEM_LABELS, INPUT_WIDTH } from '../constants';
|
||||
import { MetricDescriptor, MetricQuery } from '../types';
|
||||
import React, { FunctionComponent, useMemo } from 'react';
|
||||
|
||||
import { Aggregation, QueryEditorRow } from '.';
|
||||
import { INPUT_WIDTH, SYSTEM_LABELS } from '../constants';
|
||||
import { labelsToGroupedOptions } from '../functions';
|
||||
import { MetricDescriptor, MetricQuery } from '../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
variableOptionGroup: SelectableValue<string>;
|
||||
labels: string[];
|
||||
metricDescriptor?: MetricDescriptor;
|
||||
@ -15,6 +17,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export const GroupBy: FunctionComponent<Props> = ({
|
||||
refId,
|
||||
labels: groupBys = [],
|
||||
query,
|
||||
onChange,
|
||||
@ -30,9 +33,11 @@ export const GroupBy: FunctionComponent<Props> = ({
|
||||
<QueryEditorRow
|
||||
label="Group by"
|
||||
tooltip="You can reduce the amount of data returned for a metric by combining different time series. To combine multiple time series, you can specify a grouping and a function. Grouping is done on the basis of labels. The grouping function is used to combine the time series in the group into a single time series."
|
||||
htmlFor={`${refId}-group-by`}
|
||||
>
|
||||
<MultiSelect
|
||||
menuShouldPortal
|
||||
inputId={`${refId}-group-by`}
|
||||
width={INPUT_WIDTH}
|
||||
placeholder="Choose label"
|
||||
options={options}
|
||||
@ -47,6 +52,7 @@ export const GroupBy: FunctionComponent<Props> = ({
|
||||
crossSeriesReducer={query.crossSeriesReducer}
|
||||
groupBys={query.groupBys ?? []}
|
||||
onChange={(crossSeriesReducer) => onChange({ ...query, crossSeriesReducer })}
|
||||
refId={refId}
|
||||
></Aggregation>
|
||||
</QueryEditorRow>
|
||||
);
|
||||
|
@ -1,13 +1,13 @@
|
||||
import React, { FunctionComponent, useCallback, useMemo } from 'react';
|
||||
import { flatten } from 'lodash';
|
||||
|
||||
import { SelectableValue, toOption } from '@grafana/data';
|
||||
import { CustomControlProps } from '@grafana/ui/src/components/Select/types';
|
||||
import { Button, HorizontalGroup, Select, VerticalGroup } from '@grafana/ui';
|
||||
import { CustomControlProps } from '@grafana/ui/src/components/Select/types';
|
||||
import { flatten } from 'lodash';
|
||||
import React, { FunctionComponent, useCallback, useMemo } from 'react';
|
||||
|
||||
import { QueryEditorRow } from '.';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import { labelsToGroupedOptions, stringArrayToFilters } from '../functions';
|
||||
import { Filter } from '../types';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import { QueryEditorRow } from '.';
|
||||
|
||||
export interface Props {
|
||||
labels: { [key: string]: string[] };
|
||||
@ -20,7 +20,7 @@ const operators = ['=', '!=', '=~', '!=~'];
|
||||
|
||||
const FilterButton = React.forwardRef<HTMLButtonElement, CustomControlProps<string>>(
|
||||
({ value, isOpen, invalid, ...rest }, ref) => {
|
||||
return <Button {...rest} ref={ref} variant="secondary" icon="plus"></Button>;
|
||||
return <Button {...rest} ref={ref} variant="secondary" icon="plus" aria-label="Add filter"></Button>;
|
||||
}
|
||||
);
|
||||
FilterButton.displayName = 'FilterButton';
|
||||
@ -101,6 +101,7 @@ export const LabelFilter: FunctionComponent<Props> = ({
|
||||
<HorizontalGroup key={index} spacing="xs" width="auto">
|
||||
<Select
|
||||
menuShouldPortal
|
||||
aria-label="Filter label key"
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
formatCreateLabel={(v) => `Use label key: ${v}`}
|
||||
@ -126,6 +127,7 @@ export const LabelFilter: FunctionComponent<Props> = ({
|
||||
/>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
aria-label="Filter label value"
|
||||
width={SELECT_WIDTH}
|
||||
formatCreateLabel={(v) => `Use label value: ${v}`}
|
||||
allowCustomValue
|
||||
|
@ -1,19 +1,20 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Project, VisualMetricQueryEditor, AliasBy } from '.';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { AliasBy, Project, VisualMetricQueryEditor } from '.';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { getAlignmentPickerData } from '../functions';
|
||||
import {
|
||||
MetricQuery,
|
||||
MetricDescriptor,
|
||||
EditorMode,
|
||||
MetricKind,
|
||||
PreprocessorType,
|
||||
AlignmentTypes,
|
||||
CustomMetaData,
|
||||
ValueTypes,
|
||||
EditorMode,
|
||||
MetricDescriptor,
|
||||
MetricKind,
|
||||
MetricQuery,
|
||||
PreprocessorType,
|
||||
SLOQuery,
|
||||
ValueTypes,
|
||||
} from '../types';
|
||||
import { getAlignmentPickerData } from '../functions';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { MQLQueryEditor } from './MQLQueryEditor';
|
||||
|
||||
export interface Props {
|
||||
@ -101,6 +102,7 @@ function Editor({
|
||||
return (
|
||||
<>
|
||||
<Project
|
||||
refId={refId}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
projectName={projectName}
|
||||
datasource={datasource}
|
||||
@ -111,6 +113,7 @@ function Editor({
|
||||
|
||||
{editorMode === EditorMode.Visual && (
|
||||
<VisualMetricQueryEditor
|
||||
refId={refId}
|
||||
labels={state.labels}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
@ -130,6 +133,7 @@ function Editor({
|
||||
)}
|
||||
|
||||
<AliasBy
|
||||
refId={refId}
|
||||
value={query.aliasBy}
|
||||
onChange={(aliasBy) => {
|
||||
onChange({ ...query, aliasBy });
|
||||
|
@ -1,16 +1,17 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { startCase, uniqBy } from 'lodash';
|
||||
|
||||
import { Select, useTheme2, getSelectStyles, useStyles2 } from '@grafana/ui';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
import { SelectableValue, GrafanaTheme2 } from '@grafana/data';
|
||||
import { QueryEditorRow, QueryEditorField } from '.';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { INNER_LABEL_WIDTH, LABEL_WIDTH, SELECT_WIDTH } from '../constants';
|
||||
import { MetricDescriptor } from '../types';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
import { getSelectStyles, Select, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { startCase, uniqBy } from 'lodash';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { QueryEditorField, QueryEditorRow } from '.';
|
||||
import { INNER_LABEL_WIDTH, LABEL_WIDTH, SELECT_WIDTH } from '../constants';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { MetricDescriptor } from '../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (metricDescriptor: MetricDescriptor) => void;
|
||||
templateSrv: TemplateSrv;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
@ -135,7 +136,7 @@ export function Metrics(props: Props) {
|
||||
return (
|
||||
<>
|
||||
<QueryEditorRow>
|
||||
<QueryEditorField labelWidth={LABEL_WIDTH} label="Service">
|
||||
<QueryEditorField labelWidth={LABEL_WIDTH} label="Service" htmlFor={`${props.refId}-service`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
width={SELECT_WIDTH}
|
||||
@ -149,9 +150,10 @@ export function Metrics(props: Props) {
|
||||
...services,
|
||||
]}
|
||||
placeholder="Select Services"
|
||||
inputId={`${props.refId}-service`}
|
||||
></Select>
|
||||
</QueryEditorField>
|
||||
<QueryEditorField label="Metric name" labelWidth={INNER_LABEL_WIDTH}>
|
||||
<QueryEditorField label="Metric name" labelWidth={INNER_LABEL_WIDTH} htmlFor={`${props.refId}-select-metric`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
width={SELECT_WIDTH}
|
||||
@ -165,6 +167,7 @@ export function Metrics(props: Props) {
|
||||
...metrics,
|
||||
]}
|
||||
placeholder="Select Metric"
|
||||
inputId={`${props.refId}-select-metric`}
|
||||
></Select>
|
||||
</QueryEditorField>
|
||||
</QueryEditorRow>
|
||||
|
@ -1,18 +1,20 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { QueryEditorRow } from '.';
|
||||
import { SELECT_WIDTH } from '../constants';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
onChange: (projectName: string) => void;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
projectName: string;
|
||||
}
|
||||
|
||||
export function Project({ projectName, datasource, onChange, templateVariableOptions }: Props) {
|
||||
export function Project({ refId, projectName, datasource, onChange, templateVariableOptions }: Props) {
|
||||
const [projects, setProjects] = useState<Array<SelectableValue<string>>>([]);
|
||||
useEffect(() => {
|
||||
datasource.getProjects().then((projects) => setProjects(projects));
|
||||
@ -31,7 +33,7 @@ export function Project({ projectName, datasource, onChange, templateVariableOpt
|
||||
);
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="Project">
|
||||
<QueryEditorRow label="Project" htmlFor={`${refId}-project`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
width={SELECT_WIDTH}
|
||||
@ -41,6 +43,7 @@ export function Project({ projectName, datasource, onChange, templateVariableOpt
|
||||
options={projectsWithTemplateVariables}
|
||||
value={{ value: projectName, label: projectName }}
|
||||
placeholder="Select Project"
|
||||
inputId={`${refId}-project`}
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
);
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { QueryEditorProps, toOption } from '@grafana/data';
|
||||
import { Button, Select } from '@grafana/ui';
|
||||
import { MetricQueryEditor, SLOQueryEditor, QueryEditorRow } from './';
|
||||
import { CloudMonitoringQuery, MetricQuery, QueryType, SLOQuery, EditorMode } from '../types';
|
||||
import { SELECT_WIDTH, QUERY_TYPES } from '../constants';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { QUERY_TYPES, SELECT_WIDTH } from '../constants';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery } from '../types';
|
||||
import { MetricQueryEditor, QueryEditorRow, SLOQueryEditor } from './';
|
||||
import { defaultQuery } from './MetricQueryEditor';
|
||||
import { defaultQuery as defaultSLOQuery } from './SLO/SLOQueryEditor';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
|
||||
export type Props = QueryEditorProps<CloudMonitoringDatasource, CloudMonitoringQuery>;
|
||||
|
||||
@ -73,6 +74,7 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
htmlFor={`${query.refId}-query-type`}
|
||||
>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
@ -83,6 +85,7 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
onChange({ ...query, sloQuery, queryType: value! });
|
||||
onRunQuery();
|
||||
}}
|
||||
inputId={`${query.refId}-query-type`}
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
|
||||
@ -102,6 +105,7 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
|
||||
{queryType === QueryType.SLO && (
|
||||
<SLOQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(query: SLOQuery) => this.onQueryChange('sloQuery', query)}
|
||||
|
@ -1,47 +0,0 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Segment } from '@grafana/ui';
|
||||
import { QueryType } from '../types';
|
||||
import { QUERY_TYPES } from '../constants';
|
||||
|
||||
export interface Props {
|
||||
value: QueryType;
|
||||
onChange: (slo: QueryType) => void;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
}
|
||||
|
||||
function asQueryType(input: Array<SelectableValue<string>>) {
|
||||
const res: Array<SelectableValue<QueryType>> = [];
|
||||
input.forEach((v) => {
|
||||
if (v.value === QueryType.METRICS) {
|
||||
res.push({ ...v, value: QueryType.METRICS });
|
||||
}
|
||||
if (v.value === QueryType.SLO) {
|
||||
res.push({ ...v, value: QueryType.SLO });
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
export const QueryTypeSelector: FunctionComponent<Props> = ({ onChange, value, templateVariableOptions }) => {
|
||||
return (
|
||||
<div className="gf-form-inline">
|
||||
<label className="gf-form-label query-keyword width-9">Query Type</label>
|
||||
<Segment
|
||||
value={[...QUERY_TYPES, ...asQueryType(templateVariableOptions)].find((qt) => qt.value === value)}
|
||||
options={[
|
||||
...QUERY_TYPES,
|
||||
{
|
||||
label: 'Template Variables',
|
||||
options: templateVariableOptions,
|
||||
},
|
||||
]}
|
||||
onChange={({ value }: SelectableValue<QueryType>) => onChange(value!)}
|
||||
/>
|
||||
|
||||
<div className="gf-form gf-form--grow">
|
||||
<label className="gf-form-label gf-form-label--grow"></label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,19 +1,21 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Select } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const SLO: React.FC<Props> = ({ query, templateVariableOptions, onChange, datasource }) => {
|
||||
export const SLO: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
const [slos, setSLOs] = useState<Array<SelectableValue<string>>>([]);
|
||||
const { projectName, serviceId } = query;
|
||||
|
||||
@ -34,9 +36,10 @@ export const SLO: React.FC<Props> = ({ query, templateVariableOptions, onChange,
|
||||
}, [datasource, projectName, serviceId, templateVariableOptions]);
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="SLO">
|
||||
<QueryEditorRow label="SLO" htmlFor={`${refId}-slo`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
inputId={`${refId}-slo`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={query?.sloId && { value: query?.sloId, label: query?.sloName || query?.sloId }}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Project, AliasBy, AlignmentPeriod, AlignmentPeriodLabel, QueryEditorRow } from '..';
|
||||
import { AlignmentTypes, CustomMetaData, SLOQuery } from '../../types';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import React from 'react';
|
||||
|
||||
import { Selector, Service, SLO } from '.';
|
||||
import { AliasBy, AlignmentPeriod, AlignmentPeriodLabel, Project, QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { AlignmentTypes, CustomMetaData, SLOQuery } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
customMetaData: CustomMetaData;
|
||||
variableOptionGroup: SelectableValue<string>;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
@ -28,6 +30,7 @@ export const defaultQuery: (dataSource: CloudMonitoringDatasource) => SLOQuery =
|
||||
});
|
||||
|
||||
export function SLOQueryEditor({
|
||||
refId,
|
||||
query,
|
||||
datasource,
|
||||
onChange,
|
||||
@ -37,32 +40,37 @@ export function SLOQueryEditor({
|
||||
return (
|
||||
<>
|
||||
<Project
|
||||
refId={refId}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
projectName={query.projectName}
|
||||
datasource={datasource}
|
||||
onChange={(projectName) => onChange({ ...query, projectName })}
|
||||
/>
|
||||
<Service
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
></Service>
|
||||
<SLO
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
></SLO>
|
||||
<Selector
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
></Selector>
|
||||
|
||||
<QueryEditorRow label="Alignment period">
|
||||
<QueryEditorRow label="Alignment period" htmlFor={`${refId}-alignment-period`}>
|
||||
<AlignmentPeriod
|
||||
inputId={`${refId}-alignment-period`}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={{
|
||||
...query,
|
||||
@ -74,7 +82,7 @@ export function SLOQueryEditor({
|
||||
<AlignmentPeriodLabel datasource={datasource} customMetaData={customMetaData} />
|
||||
</QueryEditorRow>
|
||||
|
||||
<AliasBy value={query.aliasBy} onChange={(aliasBy) => onChange({ ...query, aliasBy })} />
|
||||
<AliasBy refId={refId} value={query.aliasBy} onChange={(aliasBy) => onChange({ ...query, aliasBy })} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,23 +1,26 @@
|
||||
import React from 'react';
|
||||
import { Select } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import React from 'react';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH, SELECTORS } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
import { SELECT_WIDTH, SELECTORS } from '../../constants';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const Selector: React.FC<Props> = ({ query, templateVariableOptions, onChange, datasource }) => {
|
||||
export const Selector: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
return (
|
||||
<QueryEditorRow label="Selector">
|
||||
<QueryEditorRow label="Selector" htmlFor={`${refId}-slo-selector`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
inputId={`${refId}-slo-selector`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={[...SELECTORS, ...templateVariableOptions].find((s) => s.value === query?.selectorName ?? '')}
|
||||
|
@ -1,19 +1,21 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Select } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const Service: React.FC<Props> = ({ query, templateVariableOptions, onChange, datasource }) => {
|
||||
export const Service: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
const [services, setServices] = useState<Array<SelectableValue<string>>>([]);
|
||||
const { projectName } = query;
|
||||
|
||||
@ -34,9 +36,10 @@ export const Service: React.FC<Props> = ({ query, templateVariableOptions, onCha
|
||||
}, [datasource, projectName, templateVariableOptions]);
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="Service">
|
||||
<QueryEditorRow label="Service" htmlFor={`${refId}-slo-service`}>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
inputId={`${refId}-slo-service`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={query?.serviceId && { value: query?.serviceId, label: query?.serviceName || query?.serviceId }}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import React from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Metrics, LabelFilter, GroupBy, Preprocessor, Alignment } from '.';
|
||||
import { MetricQuery, MetricDescriptor, CustomMetaData, SLOQuery } from '../types';
|
||||
import React from 'react';
|
||||
|
||||
import { Alignment, GroupBy, LabelFilter, Metrics, Preprocessor } from '.';
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
import { CustomMetaData, MetricDescriptor, MetricQuery, SLOQuery } from '../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
customMetaData: CustomMetaData;
|
||||
variableOptionGroup: SelectableValue<string>;
|
||||
onMetricTypeChange: (query: MetricDescriptor) => void;
|
||||
@ -15,6 +17,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
function Editor({
|
||||
refId,
|
||||
query,
|
||||
labels,
|
||||
datasource,
|
||||
@ -25,6 +28,7 @@ function Editor({
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<Metrics
|
||||
refId={refId}
|
||||
templateSrv={datasource.templateSrv}
|
||||
projectName={query.projectName}
|
||||
metricType={query.metricType}
|
||||
@ -42,6 +46,7 @@ function Editor({
|
||||
/>
|
||||
<Preprocessor metricDescriptor={metric} query={query} onChange={onChange} />
|
||||
<GroupBy
|
||||
refId={refId}
|
||||
labels={Object.keys(labels)}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
@ -49,6 +54,7 @@ function Editor({
|
||||
metricDescriptor={metric}
|
||||
/>
|
||||
<Alignment
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
|
@ -12,7 +12,6 @@ export { Aggregation } from './Aggregation';
|
||||
export { MetricQueryEditor } from './MetricQueryEditor';
|
||||
export { SLOQueryEditor } from './SLO/SLOQueryEditor';
|
||||
export { MQLQueryEditor } from './MQLQueryEditor';
|
||||
export { QueryTypeSelector } from './QueryType';
|
||||
export { VariableQueryField, QueryEditorRow, QueryEditorField } from './Fields';
|
||||
export { VisualMetricQueryEditor } from './VisualMetricQueryEditor';
|
||||
export { Preprocessor } from './Preprocessor';
|
||||
|
Loading…
Reference in New Issue
Block a user