123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- import { binaryScalarOperations } from './binaryScalarOperations';
- import { LabelParamEditor } from './components/LabelParamEditor';
- import {
- defaultAddOperationHandler,
- functionRendererLeft,
- functionRendererRight,
- getPromAndLokiOperationDisplayName,
- getRangeVectorParamDef,
- rangeRendererLeftWithParams,
- rangeRendererRightWithParams,
- } from './shared/operationUtils';
- import {
- QueryBuilderOperation,
- QueryBuilderOperationDef,
- QueryWithOperations,
- VisualQueryModeller,
- } from './shared/types';
- import { PromOperationId, PromVisualQuery, PromVisualQueryOperationCategory } from './types';
- export function getOperationDefinitions(): QueryBuilderOperationDef[] {
- const list: QueryBuilderOperationDef[] = [
- {
- id: PromOperationId.HistogramQuantile,
- name: 'Histogram quantile',
- params: [{ name: 'Quantile', type: 'number', options: [0.99, 0.95, 0.9, 0.75, 0.5, 0.25] }],
- defaultParams: [0.9],
- category: PromVisualQueryOperationCategory.Functions,
- renderer: functionRendererLeft,
- addOperationHandler: defaultAddOperationHandler,
- },
- {
- id: PromOperationId.LabelReplace,
- name: 'Label replace',
- params: [
- { name: 'Destination label', type: 'string' },
- { name: 'Replacement', type: 'string' },
- { name: 'Source label', type: 'string' },
- { name: 'Regex', type: 'string' },
- ],
- category: PromVisualQueryOperationCategory.Functions,
- defaultParams: ['', '$1', '', '(.*)'],
- renderer: functionRendererRight,
- addOperationHandler: defaultAddOperationHandler,
- },
- {
- id: PromOperationId.Ln,
- name: 'Ln',
- params: [],
- defaultParams: [],
- category: PromVisualQueryOperationCategory.Functions,
- renderer: functionRendererLeft,
- addOperationHandler: defaultAddOperationHandler,
- },
- createRangeFunction(PromOperationId.Changes),
- createRangeFunction(PromOperationId.Rate, true),
- createRangeFunction(PromOperationId.Irate),
- createRangeFunction(PromOperationId.Increase, true),
- createRangeFunction(PromOperationId.Idelta),
- createRangeFunction(PromOperationId.Delta),
- createFunction({
- id: PromOperationId.HoltWinters,
- params: [
- getRangeVectorParamDef(),
- { name: 'Smoothing Factor', type: 'number' },
- { name: 'Trend Factor', type: 'number' },
- ],
- defaultParams: ['$__interval', 0.5, 0.5],
- alternativesKey: 'range function',
- category: PromVisualQueryOperationCategory.RangeFunctions,
- renderer: rangeRendererRightWithParams,
- addOperationHandler: addOperationWithRangeVector,
- changeTypeHandler: operationTypeChangedHandlerForRangeFunction,
- }),
- createFunction({
- id: PromOperationId.PredictLinear,
- params: [getRangeVectorParamDef(), { name: 'Seconds from now', type: 'number' }],
- defaultParams: ['$__interval', 60],
- alternativesKey: 'range function',
- category: PromVisualQueryOperationCategory.RangeFunctions,
- renderer: rangeRendererRightWithParams,
- addOperationHandler: addOperationWithRangeVector,
- changeTypeHandler: operationTypeChangedHandlerForRangeFunction,
- }),
- createFunction({
- id: PromOperationId.QuantileOverTime,
- params: [getRangeVectorParamDef(), { name: 'Quantile', type: 'number' }],
- defaultParams: ['$__interval', 0.5],
- alternativesKey: 'overtime function',
- category: PromVisualQueryOperationCategory.RangeFunctions,
- renderer: rangeRendererLeftWithParams,
- addOperationHandler: addOperationWithRangeVector,
- changeTypeHandler: operationTypeChangedHandlerForRangeFunction,
- }),
- ...binaryScalarOperations,
- {
- id: PromOperationId.NestedQuery,
- name: 'Binary operation with query',
- params: [],
- defaultParams: [],
- category: PromVisualQueryOperationCategory.BinaryOps,
- renderer: (model, def, innerExpr) => innerExpr,
- addOperationHandler: addNestedQueryHandler,
- },
- createFunction({ id: PromOperationId.Absent }),
- createFunction({
- id: PromOperationId.Acos,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Acosh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Asin,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Asinh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Atan,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Atanh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({ id: PromOperationId.Ceil }),
- createFunction({
- id: PromOperationId.Clamp,
- name: 'Clamp',
- params: [
- { name: 'Minimum Scalar', type: 'number' },
- { name: 'Maximum Scalar', type: 'number' },
- ],
- defaultParams: [1, 1],
- }),
- createFunction({
- id: PromOperationId.ClampMax,
- params: [{ name: 'Maximum Scalar', type: 'number' }],
- defaultParams: [1],
- }),
- createFunction({
- id: PromOperationId.ClampMin,
- params: [{ name: 'Minimum Scalar', type: 'number' }],
- defaultParams: [1],
- }),
- createFunction({
- id: PromOperationId.Cos,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Cosh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.DayOfMonth,
- category: PromVisualQueryOperationCategory.Time,
- }),
- createFunction({
- id: PromOperationId.DayOfWeek,
- category: PromVisualQueryOperationCategory.Time,
- }),
- createFunction({
- id: PromOperationId.DaysInMonth,
- category: PromVisualQueryOperationCategory.Time,
- }),
- createFunction({ id: PromOperationId.Deg }),
- createRangeFunction(PromOperationId.Deriv),
- //
- createFunction({ id: PromOperationId.Exp }),
- createFunction({ id: PromOperationId.Floor }),
- createFunction({ id: PromOperationId.Group }),
- createFunction({ id: PromOperationId.Hour }),
- createFunction({
- id: PromOperationId.LabelJoin,
- params: [
- {
- name: 'Destination Label',
- type: 'string',
- editor: LabelParamEditor,
- },
- {
- name: 'Separator',
- type: 'string',
- },
- {
- name: 'Source Label',
- type: 'string',
- restParam: true,
- optional: true,
- editor: LabelParamEditor,
- },
- ],
- defaultParams: ['', ',', ''],
- renderer: labelJoinRenderer,
- addOperationHandler: labelJoinAddOperationHandler,
- }),
- createFunction({ id: PromOperationId.Log10 }),
- createFunction({ id: PromOperationId.Log2 }),
- createFunction({ id: PromOperationId.Minute }),
- createFunction({ id: PromOperationId.Month }),
- createFunction({
- id: PromOperationId.Pi,
- renderer: (model) => `${model.id}()`,
- }),
- createFunction({
- id: PromOperationId.Quantile,
- params: [{ name: 'Value', type: 'number' }],
- defaultParams: [1],
- renderer: functionRendererLeft,
- }),
- createFunction({ id: PromOperationId.Rad }),
- createRangeFunction(PromOperationId.Resets),
- createFunction({
- id: PromOperationId.Round,
- category: PromVisualQueryOperationCategory.Functions,
- params: [{ name: 'To Nearest', type: 'number' }],
- defaultParams: [1],
- }),
- createFunction({ id: PromOperationId.Scalar }),
- createFunction({ id: PromOperationId.Sgn }),
- createFunction({ id: PromOperationId.Sin, category: PromVisualQueryOperationCategory.Trigonometric }),
- createFunction({
- id: PromOperationId.Sinh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({ id: PromOperationId.Sort }),
- createFunction({ id: PromOperationId.SortDesc }),
- createFunction({ id: PromOperationId.Sqrt }),
- createFunction({ id: PromOperationId.Stddev }),
- createFunction({
- id: PromOperationId.Tan,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Tanh,
- category: PromVisualQueryOperationCategory.Trigonometric,
- }),
- createFunction({
- id: PromOperationId.Time,
- renderer: (model) => `${model.id}()`,
- }),
- createFunction({ id: PromOperationId.Timestamp }),
- createFunction({
- id: PromOperationId.Vector,
- params: [{ name: 'Value', type: 'number' }],
- defaultParams: [1],
- renderer: (model) => `${model.id}(${model.params[0]})`,
- }),
- createFunction({ id: PromOperationId.Year }),
- ];
- return list;
- }
- export function createFunction(definition: Partial<QueryBuilderOperationDef>): QueryBuilderOperationDef {
- return {
- ...definition,
- id: definition.id!,
- name: definition.name ?? getPromAndLokiOperationDisplayName(definition.id!),
- params: definition.params ?? [],
- defaultParams: definition.defaultParams ?? [],
- category: definition.category ?? PromVisualQueryOperationCategory.Functions,
- renderer: definition.renderer ?? (definition.params ? functionRendererRight : functionRendererLeft),
- addOperationHandler: definition.addOperationHandler ?? defaultAddOperationHandler,
- };
- }
- export function createRangeFunction(name: string, withRateInterval = false): QueryBuilderOperationDef {
- return {
- id: name,
- name: getPromAndLokiOperationDisplayName(name),
- params: [getRangeVectorParamDef(withRateInterval)],
- defaultParams: [withRateInterval ? '$__rate_interval' : '$__interval'],
- alternativesKey: 'range function',
- category: PromVisualQueryOperationCategory.RangeFunctions,
- renderer: operationWithRangeVectorRenderer,
- addOperationHandler: addOperationWithRangeVector,
- changeTypeHandler: operationTypeChangedHandlerForRangeFunction,
- };
- }
- function operationTypeChangedHandlerForRangeFunction(
- operation: QueryBuilderOperation,
- newDef: QueryBuilderOperationDef
- ) {
- // validate current parameter
- if (operation.params[0] === '$__rate_interval' && newDef.defaultParams[0] !== '$__rate_interval') {
- operation.params = newDef.defaultParams;
- } else if (operation.params[0] === '$__interval' && newDef.defaultParams[0] !== '$__interval') {
- operation.params = newDef.defaultParams;
- }
- return operation;
- }
- export function operationWithRangeVectorRenderer(
- model: QueryBuilderOperation,
- def: QueryBuilderOperationDef,
- innerExpr: string
- ) {
- let rangeVector = (model.params ?? [])[0] ?? '5m';
- return `${def.id}(${innerExpr}[${rangeVector}])`;
- }
- /**
- * Since there can only be one operation with range vector this will replace the current one (if one was added )
- */
- export function addOperationWithRangeVector(
- def: QueryBuilderOperationDef,
- query: PromVisualQuery,
- modeller: VisualQueryModeller
- ) {
- const newOperation: QueryBuilderOperation = {
- id: def.id,
- params: def.defaultParams,
- };
- if (query.operations.length > 0) {
- // If operation exists it has to be in the registry so no point to check if it was found
- const firstOp = modeller.getOperationDef(query.operations[0].id)!;
- if (firstOp.addOperationHandler === addOperationWithRangeVector) {
- return {
- ...query,
- operations: [newOperation, ...query.operations.slice(1)],
- };
- }
- }
- return {
- ...query,
- operations: [newOperation, ...query.operations],
- };
- }
- function addNestedQueryHandler(def: QueryBuilderOperationDef, query: PromVisualQuery): PromVisualQuery {
- return {
- ...query,
- binaryQueries: [
- ...(query.binaryQueries ?? []),
- {
- operator: '/',
- query,
- },
- ],
- };
- }
- function labelJoinRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {
- if (typeof model.params[1] !== 'string') {
- throw 'The separator must be a string';
- }
- const separator = `"${model.params[1]}"`;
- return `${model.id}(${innerExpr}, "${model.params[0]}", ${separator}, "${model.params.slice(2).join(separator)}")`;
- }
- function labelJoinAddOperationHandler<T extends QueryWithOperations>(def: QueryBuilderOperationDef, query: T) {
- const newOperation: QueryBuilderOperation = {
- id: def.id,
- params: def.defaultParams,
- };
- return {
- ...query,
- operations: [...query.operations, newOperation],
- };
- }
|