mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: remove angular (#49471)
* loki: remove angular Co-Authored-By: Joey Tawadrous <joey.tawadrous@grafana.com> * better backward-compatibility * slightly better typescript check Co-authored-by: Joey Tawadrous <joey.tawadrous@grafana.com>
This commit is contained in:
parent
e9fac9ee03
commit
cb96f51c73
@ -22,7 +22,6 @@ import { MetricSelect } from '../core/components/Select/MetricSelect';
|
|||||||
import { TagFilter } from '../core/components/TagFilter/TagFilter';
|
import { TagFilter } from '../core/components/TagFilter/TagFilter';
|
||||||
import { HelpModal } from '../core/components/help/HelpModal';
|
import { HelpModal } from '../core/components/help/HelpModal';
|
||||||
import { SearchField, SearchResults, SearchResultsFilter } from '../features/search';
|
import { SearchField, SearchResults, SearchResultsFilter } from '../features/search';
|
||||||
import { LokiAnnotationsQueryEditor } from '../plugins/datasource/loki/components/AnnotationsQueryEditor';
|
|
||||||
|
|
||||||
const { SecretFormField } = LegacyForms;
|
const { SecretFormField } = LegacyForms;
|
||||||
|
|
||||||
@ -143,13 +142,6 @@ export function registerAngularDirectives() {
|
|||||||
['onChange', { watchDepth: 'reference', wrapApply: true }],
|
['onChange', { watchDepth: 'reference', wrapApply: true }],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
react2AngularDirective('lokiAnnotationsQueryEditor', LokiAnnotationsQueryEditor, [
|
|
||||||
'expr',
|
|
||||||
'maxLines',
|
|
||||||
'instant',
|
|
||||||
'onChange',
|
|
||||||
['datasource', { watchDepth: 'reference' }],
|
|
||||||
]);
|
|
||||||
react2AngularDirective('datasourceHttpSettingsNext', DataSourceHttpSettings, [
|
react2AngularDirective('datasourceHttpSettingsNext', DataSourceHttpSettings, [
|
||||||
'defaultUrl',
|
'defaultUrl',
|
||||||
'showAccessOptions',
|
'showAccessOptions',
|
||||||
|
@ -236,7 +236,7 @@ export function getAnnotationsFromData(
|
|||||||
*/
|
*/
|
||||||
export function shouldUseMappingUI(datasource: DataSourceApi): boolean {
|
export function shouldUseMappingUI(datasource: DataSourceApi): boolean {
|
||||||
const { type } = datasource;
|
const { type } = datasource;
|
||||||
return type !== 'prometheus' && type !== 'elasticsearch';
|
return type !== 'prometheus' && type !== 'elasticsearch' && type !== 'loki';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,5 +244,5 @@ export function shouldUseMappingUI(datasource: DataSourceApi): boolean {
|
|||||||
*/
|
*/
|
||||||
export function shouldUseLegacyRunner(datasource: DataSourceApi): boolean {
|
export function shouldUseLegacyRunner(datasource: DataSourceApi): boolean {
|
||||||
const { type } = datasource;
|
const { type } = datasource;
|
||||||
return type === 'prometheus' || type === 'elasticsearch';
|
return type === 'prometheus' || type === 'elasticsearch' || type === 'loki';
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { LokiQuery } from './types';
|
|
||||||
/**
|
|
||||||
* Just a simple wrapper for a react component that is actually implementing the query editor.
|
|
||||||
*/
|
|
||||||
export class LokiAnnotationsQueryCtrl {
|
|
||||||
static templateUrl = 'partials/annotations.editor.html';
|
|
||||||
declare annotation: any;
|
|
||||||
|
|
||||||
/** @ngInject */
|
|
||||||
constructor($scope: any) {
|
|
||||||
this.annotation = $scope.ctrl.annotation;
|
|
||||||
this.annotation.target = this.annotation.target || {};
|
|
||||||
this.onQueryChange = this.onQueryChange.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
onQueryChange(query: LokiQuery) {
|
|
||||||
this.annotation.expr = query.expr;
|
|
||||||
this.annotation.maxLines = query.maxLines;
|
|
||||||
this.annotation.instant = query.instant;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +1,126 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
|
import { AnnotationQuery } from '@grafana/data';
|
||||||
|
import { EditorRow, EditorField } from '@grafana/experimental';
|
||||||
|
import { Input } from '@grafana/ui';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { LokiDatasource } from '../datasource';
|
import { getNormalizedLokiQuery } from '../query_utils';
|
||||||
import { LokiQuery } from '../types';
|
import { LokiQuery, LokiQueryType } from '../types';
|
||||||
|
|
||||||
import { LokiOptionFields } from './LokiOptionFields';
|
import { LokiOptionFields } from './LokiOptionFields';
|
||||||
import { LokiQueryField } from './LokiQueryField';
|
import { LokiQueryField } from './LokiQueryField';
|
||||||
|
import { LokiQueryEditorProps } from './types';
|
||||||
|
|
||||||
interface Props {
|
type Props = LokiQueryEditorProps & {
|
||||||
expr: string;
|
annotation?: AnnotationQuery<LokiQuery>;
|
||||||
maxLines?: number;
|
onAnnotationChange?: (annotation: AnnotationQuery<LokiQuery>) => void;
|
||||||
instant?: boolean;
|
};
|
||||||
datasource: LokiDatasource;
|
|
||||||
onChange: (query: LokiQuery) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEditor(props: Props) {
|
export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEditor(props: Props) {
|
||||||
const { expr, maxLines, instant, datasource, onChange } = props;
|
const { annotation, onAnnotationChange } = props;
|
||||||
|
|
||||||
|
// this should never happen, but we want to keep typescript happy
|
||||||
|
if (annotation === undefined || onAnnotationChange === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeQuery = (query: LokiQuery) => {
|
||||||
|
// the current version of annotations only stores an optional boolean
|
||||||
|
// field `instant` to handle the instant/range switch.
|
||||||
|
// we need to maintain compatiblity for now, so we do the same.
|
||||||
|
// we explicitly call `getNormalizedLokiQuery` to make sure `queryType`
|
||||||
|
// is set up correctly.
|
||||||
|
const instant = getNormalizedLokiQuery(query).queryType === LokiQueryType.Instant;
|
||||||
|
onAnnotationChange({
|
||||||
|
...annotation,
|
||||||
|
expr: query.expr,
|
||||||
|
maxLines: query.maxLines,
|
||||||
|
instant,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const queryWithRefId: LokiQuery = {
|
const queryWithRefId: LokiQuery = {
|
||||||
refId: '',
|
refId: '',
|
||||||
expr,
|
expr: annotation.expr,
|
||||||
maxLines,
|
maxLines: annotation.maxLines,
|
||||||
instant,
|
instant: annotation.instant,
|
||||||
|
queryType: annotation.queryType,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="gf-form-group">
|
<>
|
||||||
<LokiQueryField
|
<div className="gf-form-group">
|
||||||
datasource={datasource}
|
<LokiQueryField
|
||||||
query={queryWithRefId}
|
datasource={props.datasource}
|
||||||
onChange={onChange}
|
query={queryWithRefId}
|
||||||
onRunQuery={() => {}}
|
onChange={onChangeQuery}
|
||||||
onBlur={() => {}}
|
onRunQuery={() => {}}
|
||||||
history={[]}
|
onBlur={() => {}}
|
||||||
ExtraFieldElement={
|
history={[]}
|
||||||
<LokiOptionFields
|
ExtraFieldElement={
|
||||||
lineLimitValue={queryWithRefId?.maxLines?.toString() || ''}
|
<LokiOptionFields
|
||||||
resolution={queryWithRefId.resolution || 1}
|
lineLimitValue={queryWithRefId?.maxLines?.toString() || ''}
|
||||||
query={queryWithRefId}
|
resolution={queryWithRefId.resolution || 1}
|
||||||
onRunQuery={() => {}}
|
query={queryWithRefId}
|
||||||
onChange={onChange}
|
onRunQuery={() => {}}
|
||||||
|
onChange={onChangeQuery}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<EditorRow>
|
||||||
|
<EditorField
|
||||||
|
label="Title"
|
||||||
|
tooltip={
|
||||||
|
'Use either the name or a pattern. For example, {{instance}} is replaced with label value for the label instance.'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="alertname"
|
||||||
|
value={annotation.titleFormat}
|
||||||
|
onChange={(event) => {
|
||||||
|
onAnnotationChange({
|
||||||
|
...annotation,
|
||||||
|
titleFormat: event.currentTarget.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
</EditorField>
|
||||||
/>
|
<EditorField label="Tags">
|
||||||
</div>
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="label1,label2"
|
||||||
|
value={annotation.tagKeys}
|
||||||
|
onChange={(event) => {
|
||||||
|
onAnnotationChange({
|
||||||
|
...annotation,
|
||||||
|
tagKeys: event.currentTarget.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</EditorField>
|
||||||
|
<EditorField
|
||||||
|
label="Text"
|
||||||
|
tooltip={
|
||||||
|
'Use either the name or a pattern. For example, {{instance}} is replaced with label value for the label instance.'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="instance"
|
||||||
|
value={annotation.textFormat}
|
||||||
|
onChange={(event) => {
|
||||||
|
onAnnotationChange({
|
||||||
|
...annotation,
|
||||||
|
textFormat: event.currentTarget.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</EditorField>
|
||||||
|
</EditorRow>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -47,6 +47,7 @@ import { renderLegendFormat } from '../prometheus/legend';
|
|||||||
|
|
||||||
import { addLabelToQuery } from './add_label_to_query';
|
import { addLabelToQuery } from './add_label_to_query';
|
||||||
import { transformBackendResult } from './backendResultTransformer';
|
import { transformBackendResult } from './backendResultTransformer';
|
||||||
|
import { LokiAnnotationsQueryEditor } from './components/AnnotationsQueryEditor';
|
||||||
import { DEFAULT_RESOLUTION } from './components/LokiOptionFields';
|
import { DEFAULT_RESOLUTION } from './components/LokiOptionFields';
|
||||||
import LanguageProvider from './language_provider';
|
import LanguageProvider from './language_provider';
|
||||||
import { escapeLabelValueInSelector } from './language_utils';
|
import { escapeLabelValueInSelector } from './language_utils';
|
||||||
@ -118,6 +119,9 @@ export class LokiDatasource
|
|||||||
const settingsData = instanceSettings.jsonData || {};
|
const settingsData = instanceSettings.jsonData || {};
|
||||||
this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES;
|
this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES;
|
||||||
this.useBackendMode = config.featureToggles.lokiBackendMode ?? false;
|
this.useBackendMode = config.featureToggles.lokiBackendMode ?? false;
|
||||||
|
this.annotations = {
|
||||||
|
QueryEditor: LokiAnnotationsQueryEditor,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_request(apiUrl: string, data?: any, options?: Partial<BackendSrvRequest>): Observable<Record<string, any>> {
|
_request(apiUrl: string, data?: any, options?: Partial<BackendSrvRequest>): Observable<Record<string, any>> {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { DataSourcePlugin } from '@grafana/data';
|
import { DataSourcePlugin } from '@grafana/data';
|
||||||
|
|
||||||
import { LokiAnnotationsQueryCtrl } from './LokiAnnotationsQueryCtrl';
|
|
||||||
import LokiCheatSheet from './components/LokiCheatSheet';
|
import LokiCheatSheet from './components/LokiCheatSheet';
|
||||||
import LokiQueryEditorByApp from './components/LokiQueryEditorByApp';
|
import LokiQueryEditorByApp from './components/LokiQueryEditorByApp';
|
||||||
import { ConfigEditor } from './configuration/ConfigEditor';
|
import { ConfigEditor } from './configuration/ConfigEditor';
|
||||||
@ -9,5 +8,4 @@ import { LokiDatasource } from './datasource';
|
|||||||
export const plugin = new DataSourcePlugin(LokiDatasource)
|
export const plugin = new DataSourcePlugin(LokiDatasource)
|
||||||
.setQueryEditor(LokiQueryEditorByApp)
|
.setQueryEditor(LokiQueryEditorByApp)
|
||||||
.setConfigEditor(ConfigEditor)
|
.setConfigEditor(ConfigEditor)
|
||||||
.setQueryEditorHelp(LokiCheatSheet)
|
.setQueryEditorHelp(LokiCheatSheet);
|
||||||
.setAnnotationQueryCtrl(LokiAnnotationsQueryCtrl);
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
<loki-annotations-query-editor
|
|
||||||
expr="ctrl.annotation.expr"
|
|
||||||
max-lines="ctrl.annotation.maxLines"
|
|
||||||
instant="ctrl.annotation.instant"
|
|
||||||
on-change="ctrl.onQueryChange"
|
|
||||||
datasource="ctrl.datasource"
|
|
||||||
>
|
|
||||||
</loki-annotations-query-editor>
|
|
||||||
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<h5 class="section-heading">Field formats<tip>For title and text fields, use either the name or a pattern. For example, {{instance}} is replaced with label value for the label instance.</tip></h5>
|
|
||||||
<div class="gf-form-inline">
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-5">Title</span>
|
|
||||||
<input type="text" class="gf-form-input max-width-9" ng-model='ctrl.annotation.titleFormat' placeholder="alertname"></input>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-5">Tags</span>
|
|
||||||
<input type="text" class="gf-form-input max-width-9" ng-model='ctrl.annotation.tagKeys' placeholder="label1,label2"></input>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form-inline">
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-5">Text</span>
|
|
||||||
<input type="text" class="gf-form-input max-width-9" ng-model='ctrl.annotation.textFormat' placeholder="instance"></input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue
Block a user