diff --git a/eslint.config.js b/eslint.config.js index d5bd122f12c..fd4802f10d4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -311,6 +311,7 @@ module.exports = [ files: [ 'public/app/!(plugins)/**/*.{ts,tsx,js,jsx}', 'packages/grafana-ui/**/*.{ts,tsx,js,jsx}', + 'packages/grafana-data/**/*.{ts,tsx,js,jsx}', 'packages/grafana-sql/**/*.{ts,tsx,js,jsx}', 'packages/grafana-prometheus/**/*.{ts,tsx,js,jsx}', ...pluginsToTranslate.map((plugin) => `${plugin}/**/*.{ts,tsx,js,jsx}`), diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index dc5fb4cfa15..6012ea32a6e 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -56,6 +56,7 @@ }, "dependencies": { "@braintree/sanitize-url": "7.0.1", + "@grafana/i18n": "12.1.0-pre", "@grafana/schema": "12.1.0-pre", "@leeoniya/ufuzzy": "1.0.18", "@types/d3-interpolate": "^3.0.0", diff --git a/packages/grafana-data/src/datetime/moment_wrapper.ts b/packages/grafana-data/src/datetime/moment_wrapper.ts index 4b5bfc44290..0120e016d56 100644 --- a/packages/grafana-data/src/datetime/moment_wrapper.ts +++ b/packages/grafana-data/src/datetime/moment_wrapper.ts @@ -1,4 +1,5 @@ import moment, { Moment, MomentInput, DurationInputArg1, DurationInputArg2 } from 'moment'; +import { tz } from 'moment-timezone'; import { TimeZone } from '../types/time'; /* eslint-disable id-blacklist, no-restricted-imports */ @@ -130,9 +131,9 @@ export const dateTimeForTimeZone = ( let result: moment.Moment; if (typeof input === 'string' && formatInput) { - result = moment.tz(input, formatInput, timezone); + result = tz(input, formatInput, timezone); } else { - result = moment.tz(input, timezone); + result = tz(input, timezone); } if (isDateTime(result)) { diff --git a/packages/grafana-data/src/valueFormats/categories.ts b/packages/grafana-data/src/valueFormats/categories.ts index e1e1bdf51ba..6eb64037208 100644 --- a/packages/grafana-data/src/valueFormats/categories.ts +++ b/packages/grafana-data/src/valueFormats/categories.ts @@ -1,3 +1,5 @@ +import { t } from '@grafana/i18n'; + import { toHex, sci, toHex0x, toPercent, toPercentUnit } from './arithmeticFormatters'; import { dateTimeAsIso, @@ -36,408 +38,1546 @@ import { export const getCategories = (): ValueFormatCategory[] => [ { - name: 'Misc', + name: t('grafana-data.valueFormats.categories.misc.name', 'Misc'), formats: [ - { name: 'Number', id: 'none', fn: toFixedUnit('') }, - { name: 'String', id: 'string', fn: stringFormater }, { - name: 'short', + name: t('grafana-data.valueFormats.categories.misc.formats.name-number', 'Number'), + id: 'none', + fn: toFixedUnit(''), + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-string', 'String'), + id: 'string', + fn: stringFormater, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-short', 'short'), id: 'short', fn: scaledUnits(1000, ['', ' K', ' Mil', ' Bil', ' Tri', ' Quadr', ' Quint', ' Sext', ' Sept']), }, - { name: 'SI short', id: 'sishort', fn: SIPrefix('') }, - { name: 'Percent (0-100)', id: 'percent', fn: toPercent }, - { name: 'Percent (0.0-1.0)', id: 'percentunit', fn: toPercentUnit }, - { name: 'Humidity (%H)', id: 'humidity', fn: toFixedUnit('%H') }, - { name: 'Decibel', id: 'dB', fn: toFixedUnit('dB') }, - { name: 'Candela (cd)', id: 'candela', fn: SIPrefix('cd') }, - { name: 'Hexadecimal (0x)', id: 'hex0x', fn: toHex0x }, - { name: 'Hexadecimal', id: 'hex', fn: toHex }, - { name: 'Scientific notation', id: 'sci', fn: sci }, - { name: 'Locale format', id: 'locale', fn: locale }, - { name: 'Pixels', id: 'pixel', fn: toFixedUnit('px') }, - ], - }, - { - name: 'Acceleration', - formats: [ - { name: 'Meters/sec²', id: 'accMS2', fn: toFixedUnit('m/sec²') }, - { name: 'Feet/sec²', id: 'accFS2', fn: toFixedUnit('f/sec²') }, - { name: 'G unit', id: 'accG', fn: toFixedUnit('g') }, - ], - }, - { - name: 'Angle', - formats: [ - { name: 'Degrees (°)', id: 'degree', fn: toFixedUnit('°') }, - { name: 'Radians', id: 'radian', fn: toFixedUnit('rad') }, - { name: 'Gradian', id: 'grad', fn: toFixedUnit('grad') }, - { name: 'Arc Minutes', id: 'arcmin', fn: toFixedUnit('arcmin') }, - { name: 'Arc Seconds', id: 'arcsec', fn: toFixedUnit('arcsec') }, - ], - }, - { - name: 'Area', - formats: [ - { name: 'Square Meters (m²)', id: 'areaM2', fn: toFixedUnit('m²') }, - { name: 'Square Feet (ft²)', id: 'areaF2', fn: toFixedUnit('ft²') }, - { name: 'Square Miles (mi²)', id: 'areaMI2', fn: toFixedUnit('mi²') }, - { name: 'Acres (ac)', id: 'acres', fn: toFixedUnit('ac') }, - { name: 'Hectares (ha)', id: 'hectares', fn: toFixedUnit('ha') }, - ], - }, - { - name: 'Computation', - formats: [ - { name: 'FLOP/s', id: 'flops', fn: SIPrefix('FLOPS') }, - { name: 'MFLOP/s', id: 'mflops', fn: SIPrefix('FLOPS', 2) }, - { name: 'GFLOP/s', id: 'gflops', fn: SIPrefix('FLOPS', 3) }, - { name: 'TFLOP/s', id: 'tflops', fn: SIPrefix('FLOPS', 4) }, - { name: 'PFLOP/s', id: 'pflops', fn: SIPrefix('FLOPS', 5) }, - { name: 'EFLOP/s', id: 'eflops', fn: SIPrefix('FLOPS', 6) }, - { name: 'ZFLOP/s', id: 'zflops', fn: SIPrefix('FLOPS', 7) }, - { name: 'YFLOP/s', id: 'yflops', fn: SIPrefix('FLOPS', 8) }, - ], - }, - { - name: 'Concentration', - formats: [ - { name: 'parts-per-million (ppm)', id: 'ppm', fn: toFixedUnit('ppm') }, - { name: 'parts-per-billion (ppb)', id: 'conppb', fn: toFixedUnit('ppb') }, - { name: 'nanogram per cubic meter (ng/m³)', id: 'conngm3', fn: toFixedUnit('ng/m³') }, - { name: 'nanogram per normal cubic meter (ng/Nm³)', id: 'conngNm3', fn: toFixedUnit('ng/Nm³') }, - { name: 'microgram per cubic meter (μg/m³)', id: 'conμgm3', fn: toFixedUnit('μg/m³') }, - { name: 'microgram per normal cubic meter (μg/Nm³)', id: 'conμgNm3', fn: toFixedUnit('μg/Nm³') }, - { name: 'milligram per cubic meter (mg/m³)', id: 'conmgm3', fn: toFixedUnit('mg/m³') }, - { name: 'milligram per normal cubic meter (mg/Nm³)', id: 'conmgNm3', fn: toFixedUnit('mg/Nm³') }, - { name: 'gram per cubic meter (g/m³)', id: 'congm3', fn: toFixedUnit('g/m³') }, - { name: 'gram per normal cubic meter (g/Nm³)', id: 'congNm3', fn: toFixedUnit('g/Nm³') }, - { name: 'milligrams per decilitre (mg/dL)', id: 'conmgdL', fn: toFixedUnit('mg/dL') }, - { name: 'millimoles per litre (mmol/L)', id: 'conmmolL', fn: toFixedUnit('mmol/L') }, - ], - }, - { - name: 'Currency', - formats: [ - { name: 'Dollars ($)', id: 'currencyUSD', fn: currency('$') }, - { name: 'Pounds (£)', id: 'currencyGBP', fn: currency('£') }, - { name: 'Euro (€)', id: 'currencyEUR', fn: currency('€') }, - { name: 'Yen (¥)', id: 'currencyJPY', fn: currency('¥') }, - { name: 'Rubles (₽)', id: 'currencyRUB', fn: currency('₽') }, - { name: 'Hryvnias (₴)', id: 'currencyUAH', fn: currency('₴') }, - { name: 'Real (R$)', id: 'currencyBRL', fn: currency('R$') }, - { name: 'Danish Krone (kr)', id: 'currencyDKK', fn: currency('kr', true) }, - { name: 'Icelandic Króna (kr)', id: 'currencyISK', fn: currency('kr', true) }, - { name: 'Norwegian Krone (kr)', id: 'currencyNOK', fn: currency('kr', true) }, - { name: 'Swedish Krona (kr)', id: 'currencySEK', fn: currency('kr', true) }, - { name: 'Czech koruna (czk)', id: 'currencyCZK', fn: currency('czk') }, - { name: 'Swiss franc (CHF)', id: 'currencyCHF', fn: currency('CHF') }, - { name: 'Polish Złoty (PLN)', id: 'currencyPLN', fn: currency('PLN') }, - { name: 'Bitcoin (฿)', id: 'currencyBTC', fn: currency('฿') }, - { name: 'Milli Bitcoin (฿)', id: 'currencymBTC', fn: currency('mBTC') }, - { name: 'Micro Bitcoin (฿)', id: 'currencyμBTC', fn: currency('μBTC') }, - { name: 'South African Rand (R)', id: 'currencyZAR', fn: currency('R') }, - { name: 'Indian Rupee (₹)', id: 'currencyINR', fn: currency('₹') }, - { name: 'South Korean Won (₩)', id: 'currencyKRW', fn: currency('₩') }, - { name: 'Indonesian Rupiah (Rp)', id: 'currencyIDR', fn: currency('Rp') }, - { name: 'Philippine Peso (PHP)', id: 'currencyPHP', fn: currency('PHP') }, - { name: 'Vietnamese Dong (VND)', id: 'currencyVND', fn: currency('đ', true) }, - { name: 'Turkish Lira (₺)', id: 'currencyTRY', fn: currency('₺', true) }, - { name: 'Malaysian Ringgit (RM)', id: 'currencyMYR', fn: currency('RM') }, - { name: 'CFP franc (XPF)', id: 'currencyXPF', fn: currency('XPF') }, - { name: 'Bulgarian Lev (BGN)', id: 'currencyBGN', fn: currency('BGN') }, - { name: 'Guaraní (₲)', id: 'currencyPYG', fn: currency('₲') }, - { name: 'Uruguay Peso (UYU)', id: 'currencyUYU', fn: currency('UYU') }, - { name: 'Israeli New Shekels (₪)', id: 'currencyILS', fn: currency('₪') }, - ], - }, - { - name: 'Data', - formats: [ - { name: 'bytes(IEC)', id: 'bytes', fn: binaryPrefix('B') }, - { name: 'bytes(SI)', id: 'decbytes', fn: SIPrefix('B') }, - { name: 'bits(IEC)', id: 'bits', fn: binaryPrefix('b') }, - { name: 'bits(SI)', id: 'decbits', fn: SIPrefix('b') }, - { name: 'kibibytes', id: 'kbytes', fn: binaryPrefix('B', 1) }, - { name: 'kilobytes', id: 'deckbytes', fn: SIPrefix('B', 1) }, - { name: 'mebibytes', id: 'mbytes', fn: binaryPrefix('B', 2) }, - { name: 'megabytes', id: 'decmbytes', fn: SIPrefix('B', 2) }, - { name: 'gibibytes', id: 'gbytes', fn: binaryPrefix('B', 3) }, - { name: 'gigabytes', id: 'decgbytes', fn: SIPrefix('B', 3) }, - { name: 'tebibytes', id: 'tbytes', fn: binaryPrefix('B', 4) }, - { name: 'terabytes', id: 'dectbytes', fn: SIPrefix('B', 4) }, - { name: 'pebibytes', id: 'pbytes', fn: binaryPrefix('B', 5) }, - { name: 'petabytes', id: 'decpbytes', fn: SIPrefix('B', 5) }, - ], - }, - { - name: 'Data rate', - formats: [ - { name: 'packets/sec', id: 'pps', fn: SIPrefix('p/s') }, - { name: 'bytes/sec(IEC)', id: 'binBps', fn: binaryPrefix('B/s') }, - { name: 'bytes/sec(SI)', id: 'Bps', fn: SIPrefix('B/s') }, - { name: 'bits/sec(IEC)', id: 'binbps', fn: binaryPrefix('b/s') }, - { name: 'bits/sec(SI)', id: 'bps', fn: SIPrefix('b/s') }, - { name: 'kibibytes/sec', id: 'KiBs', fn: binaryPrefix('B/s', 1) }, - { name: 'kibibits/sec', id: 'Kibits', fn: binaryPrefix('b/s', 1) }, - { name: 'kilobytes/sec', id: 'KBs', fn: SIPrefix('B/s', 1) }, - { name: 'kilobits/sec', id: 'Kbits', fn: SIPrefix('b/s', 1) }, - { name: 'mebibytes/sec', id: 'MiBs', fn: binaryPrefix('B/s', 2) }, - { name: 'mebibits/sec', id: 'Mibits', fn: binaryPrefix('b/s', 2) }, - { name: 'megabytes/sec', id: 'MBs', fn: SIPrefix('B/s', 2) }, - { name: 'megabits/sec', id: 'Mbits', fn: SIPrefix('b/s', 2) }, - { name: 'gibibytes/sec', id: 'GiBs', fn: binaryPrefix('B/s', 3) }, - { name: 'gibibits/sec', id: 'Gibits', fn: binaryPrefix('b/s', 3) }, - { name: 'gigabytes/sec', id: 'GBs', fn: SIPrefix('B/s', 3) }, - { name: 'gigabits/sec', id: 'Gbits', fn: SIPrefix('b/s', 3) }, - { name: 'tebibytes/sec', id: 'TiBs', fn: binaryPrefix('B/s', 4) }, - { name: 'tebibits/sec', id: 'Tibits', fn: binaryPrefix('b/s', 4) }, - { name: 'terabytes/sec', id: 'TBs', fn: SIPrefix('B/s', 4) }, - { name: 'terabits/sec', id: 'Tbits', fn: SIPrefix('b/s', 4) }, - { name: 'pebibytes/sec', id: 'PiBs', fn: binaryPrefix('B/s', 5) }, - { name: 'pebibits/sec', id: 'Pibits', fn: binaryPrefix('b/s', 5) }, - { name: 'petabytes/sec', id: 'PBs', fn: SIPrefix('B/s', 5) }, - { name: 'petabits/sec', id: 'Pbits', fn: SIPrefix('b/s', 5) }, - ], - }, - { - name: 'Date & time', - formats: [ - { name: 'Datetime ISO', id: 'dateTimeAsIso', fn: dateTimeAsIso }, - { name: 'Datetime ISO (No date if today)', id: 'dateTimeAsIsoNoDateIfToday', fn: dateTimeAsIsoNoDateIfToday }, - { name: 'Datetime US', id: 'dateTimeAsUS', fn: dateTimeAsUS }, - { name: 'Datetime US (No date if today)', id: 'dateTimeAsUSNoDateIfToday', fn: dateTimeAsUSNoDateIfToday }, - { name: 'Datetime local', id: 'dateTimeAsLocal', fn: getDateTimeAsLocalFormat() }, { - name: 'Datetime local (No date if today)', + name: t('grafana-data.valueFormats.categories.misc.formats.name-si-short', 'SI short'), + id: 'sishort', + fn: SIPrefix(''), + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-percent-100', 'Percent (0-100)'), + id: 'percent', + fn: toPercent, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-percent-1', 'Percent (0.0-1.0)'), + id: 'percentunit', + fn: toPercentUnit, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-humidity', 'Humidity (%H)'), + id: 'humidity', + fn: toFixedUnit('%H'), + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-decibel', 'Decibel'), + id: 'dB', + fn: toFixedUnit('dB'), + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-candala', 'Candela (cd)'), + id: 'candela', + fn: SIPrefix('cd'), + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-hexadecimal-0x', 'Hexadecimal (0x)'), + id: 'hex0x', + fn: toHex0x, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-hexadecimal', 'Hexadecimal'), + id: 'hex', + fn: toHex, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-scientific', 'Scientific notation'), + id: 'sci', + fn: sci, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-locale', 'Locale format'), + id: 'locale', + fn: locale, + }, + { + name: t('grafana-data.valueFormats.categories.misc.formats.name-pixels', 'Pixels'), + id: 'pixel', + fn: toFixedUnit('px'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.acceleration.name', 'Acceleration'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.acceleration.formats.name-meters-sec', 'Meters/sec²'), + id: 'accMS2', + fn: toFixedUnit('m/sec²'), + }, + { + name: t('grafana-data.valueFormats.categories.acceleration.formats.name-feet-sec', 'Feet/sec²'), + id: 'accFS2', + fn: toFixedUnit('f/sec²'), + }, + { + name: t('grafana-data.valueFormats.categories.acceleration.formats.name-g-unit', 'G unit'), + id: 'accG', + fn: toFixedUnit('g'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.angle.name', 'Angle'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.angle.formats.name-degrees', 'Degrees (°)'), + id: 'degree', + fn: toFixedUnit('°'), + }, + { + name: t('grafana-data.valueFormats.categories.angle.formats.name-radians', 'Radians'), + id: 'radian', + fn: toFixedUnit('rad'), + }, + { + name: t('grafana-data.valueFormats.categories.angle.formats.name-gradian', 'Gradian'), + id: 'grad', + fn: toFixedUnit('grad'), + }, + { + name: t('grafana-data.valueFormats.categories.angle.formats.name-arc-minutes', 'Arc Minutes'), + id: 'arcmin', + fn: toFixedUnit('arcmin'), + }, + { + name: t('grafana-data.valueFormats.categories.angle.formats.name-arc-seconds', 'Arc Seconds'), + id: 'arcsec', + fn: toFixedUnit('arcsec'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.area.name', 'Area'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.area.formats.name-square-meters', 'Square Meters (m²)'), + id: 'areaM2', + fn: toFixedUnit('m²'), + }, + { + name: t('grafana-data.valueFormats.categories.area.formats.name-square-feet', 'Square Feet (ft²)'), + id: 'areaF2', + fn: toFixedUnit('ft²'), + }, + { + name: t('grafana-data.valueFormats.categories.area.formats.name-square-miles', 'Square Miles (mi²)'), + id: 'areaMI2', + fn: toFixedUnit('mi²'), + }, + { + name: t('grafana-data.valueFormats.categories.area.formats.name-acres', 'Acres (ac)'), + id: 'acres', + fn: toFixedUnit('ac'), + }, + { + name: t('grafana-data.valueFormats.categories.area.formats.name-hectares', 'Hectares (ha)'), + id: 'hectares', + fn: toFixedUnit('ha'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.computation.name', 'Computation'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-flops', 'FLOP/s'), + id: 'flops', + fn: SIPrefix('FLOPS'), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-mflops', 'MFLOP/s'), + id: 'mflops', + fn: SIPrefix('FLOPS', 2), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-gflops', 'GFLOP/s'), + id: 'gflops', + fn: SIPrefix('FLOPS', 3), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-tflops', 'TFLOP/s'), + id: 'tflops', + fn: SIPrefix('FLOPS', 4), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-pflops', 'PFLOP/s'), + id: 'pflops', + fn: SIPrefix('FLOPS', 5), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-eflops', 'EFLOP/s'), + id: 'eflops', + fn: SIPrefix('FLOPS', 6), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-zflops', 'ZFLOP/s'), + id: 'zflops', + fn: SIPrefix('FLOPS', 7), + }, + { + name: t('grafana-data.valueFormats.categories.computation.formats.name-yflops', 'YFLOP/s'), + id: 'yflops', + fn: SIPrefix('FLOPS', 8), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.concentration.name', 'Concentration'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.concentration.formats.name-ppm', 'parts-per-million (ppm)'), + id: 'ppm', + fn: toFixedUnit('ppm'), + }, + { + name: t('grafana-data.valueFormats.categories.concentration.formats.name-ppb', 'parts-per-billion (ppb)'), + id: 'conppb', + fn: toFixedUnit('ppb'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-ng-m3', + 'nanogram per cubic meter (ng/m³)' + ), + id: 'conngm3', + fn: toFixedUnit('ng/m³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-ng-nm3', + 'nanogram per normal cubic meter (ng/Nm³)' + ), + id: 'conngNm3', + fn: toFixedUnit('ng/Nm³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-ug-m3', + 'microgram per cubic meter (μg/m³)' + ), + id: 'conμgm3', + fn: toFixedUnit('μg/m³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-ug-nm3', + 'microgram per normal cubic meter (μg/Nm³)' + ), + id: 'conμgNm3', + fn: toFixedUnit('μg/Nm³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-mg-m3', + 'milligram per cubic meter (mg/m³)' + ), + id: 'conmgm3', + fn: toFixedUnit('mg/m³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-mg-nm3', + 'milligram per normal cubic meter (mg/Nm³)' + ), + id: 'conmgNm3', + fn: toFixedUnit('mg/Nm³'), + }, + { + name: t('grafana-data.valueFormats.categories.concentration.formats.name-g-m3', 'gram per cubic meter (g/m³)'), + id: 'congm3', + fn: toFixedUnit('g/m³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-g-nm3', + 'gram per normal cubic meter (g/Nm³)' + ), + id: 'congNm3', + fn: toFixedUnit('g/Nm³'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-mg-dl', + 'milligrams per decilitre (mg/dL)' + ), + id: 'conmgdL', + fn: toFixedUnit('mg/dL'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.concentration.formats.name-mmol-l', + 'millimoles per litre (mmol/L)' + ), + id: 'conmmolL', + fn: toFixedUnit('mmol/L'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.currency.name', 'Currency'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-usd', 'Dollars ($)'), + id: 'currencyUSD', + fn: currency('$'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-gbp', 'Pounds (£)'), + id: 'currencyGBP', + fn: currency('£'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-eur', 'Euro (€)'), + id: 'currencyEUR', + fn: currency('€'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-jpy', 'Yen (¥)'), + id: 'currencyJPY', + fn: currency('¥'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-rub', 'Rubles (₽)'), + id: 'currencyRUB', + fn: currency('₽'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-uah', 'Hryvnias (₴)'), + id: 'currencyUAH', + fn: currency('₴'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-brl', 'Real (R$)'), + id: 'currencyBRL', + fn: currency('R$'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-dkk', 'Danish Krone (kr)'), + id: 'currencyDKK', + fn: currency('kr', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-isk', 'Icelandic Króna (kr)'), + id: 'currencyISK', + fn: currency('kr', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-nok', 'Norwegian Krone (kr)'), + id: 'currencyNOK', + fn: currency('kr', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-sek', 'Swedish Krona (kr)'), + id: 'currencySEK', + fn: currency('kr', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-czk', 'Czech koruna (czk)'), + id: 'currencyCZK', + fn: currency('czk'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-chf', 'Swiss franc (CHF)'), + id: 'currencyCHF', + fn: currency('CHF'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-pln', 'Polish Złoty (PLN)'), + id: 'currencyPLN', + fn: currency('PLN'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-btc', 'Bitcoin (฿)'), + id: 'currencyBTC', + fn: currency('฿'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-mbtc', 'Milli Bitcoin (฿)'), + id: 'currencymBTC', + fn: currency('mBTC'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-ubtc', 'Micro Bitcoin (฿)'), + id: 'currencyμBTC', + fn: currency('μBTC'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-zar', 'South African Rand (R)'), + id: 'currencyZAR', + fn: currency('R'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-inr', 'Indian Rupee (₹)'), + id: 'currencyINR', + fn: currency('₹'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-krw', 'South Korean Won (₩)'), + id: 'currencyKRW', + fn: currency('₩'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-idr', 'Indonesian Rupiah (Rp)'), + id: 'currencyIDR', + fn: currency('Rp'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-php', 'Philippine Peso (PHP)'), + id: 'currencyPHP', + fn: currency('PHP'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-vnd', 'Vietnamese Dong (VND)'), + id: 'currencyVND', + fn: currency('đ', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-try', 'Turkish Lira (₺)'), + id: 'currencyTRY', + fn: currency('₺', true), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-myr', 'Malaysian Ringgit (RM)'), + id: 'currencyMYR', + fn: currency('RM'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-xpf', 'CFP franc (XPF)'), + id: 'currencyXPF', + fn: currency('XPF'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-bgn', 'Bulgarian Lev (BGN)'), + id: 'currencyBGN', + fn: currency('BGN'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-pyg', 'Guaraní (₲)'), + id: 'currencyPYG', + fn: currency('₲'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-uyu', 'Uruguay Peso (UYU)'), + id: 'currencyUYU', + fn: currency('UYU'), + }, + { + name: t('grafana-data.valueFormats.categories.currency.formats.name-ils', 'Israeli New Shekels (₪)'), + id: 'currencyILS', + fn: currency('₪'), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.data.name', 'Data'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.data.formats.name-bytes-iec', 'bytes(IEC)'), + id: 'bytes', + fn: binaryPrefix('B'), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-bytes-si', 'bytes(SI)'), + id: 'decbytes', + fn: SIPrefix('B'), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-bits-iec', 'bits(IEC)'), + id: 'bits', + fn: binaryPrefix('b'), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-bits-si', 'bits(SI)'), + id: 'decbits', + fn: SIPrefix('b'), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-kibibytes', 'kibibytes'), + id: 'kbytes', + fn: binaryPrefix('B', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-kilobytes', 'kilobytes'), + id: 'deckbytes', + fn: SIPrefix('B', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-mebibytes', 'mebibytes'), + id: 'mbytes', + fn: binaryPrefix('B', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-megabytes', 'megabytes'), + id: 'decmbytes', + fn: SIPrefix('B', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-gibibytes', 'gibibytes'), + id: 'gbytes', + fn: binaryPrefix('B', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-gigabytes', 'gigabytes'), + id: 'decgbytes', + fn: SIPrefix('B', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-tebibytes', 'tebibytes'), + id: 'tbytes', + fn: binaryPrefix('B', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-terabytes', 'terabytes'), + id: 'dectbytes', + fn: SIPrefix('B', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-pebibytes', 'pebibytes'), + id: 'pbytes', + fn: binaryPrefix('B', 5), + }, + { + name: t('grafana-data.valueFormats.categories.data.formats.name-petabytes', 'petabytes'), + id: 'decpbytes', + fn: SIPrefix('B', 5), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.name', 'Data rate'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-packets-sec', 'packets/sec'), + id: 'pps', + fn: SIPrefix('p/s'), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-bytes-sec-iec', 'bytes/sec(IEC)'), + id: 'binBps', + fn: binaryPrefix('B/s'), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-bytes-sec-si', 'bytes/sec(SI)'), + id: 'Bps', + fn: SIPrefix('B/s'), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-bits-sec-iec', 'bits/sec(IEC)'), + id: 'binbps', + fn: binaryPrefix('b/s'), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-bits-sec-si', 'bits/sec(SI)'), + id: 'bps', + fn: SIPrefix('b/s'), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-kibibytes-sec', 'kibibytes/sec'), + id: 'KiBs', + fn: binaryPrefix('B/s', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-kibibits-sec', 'kibibits/sec'), + id: 'Kibits', + fn: binaryPrefix('b/s', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-kilobytes-sec', 'kilobytes/sec'), + id: 'KBs', + fn: SIPrefix('B/s', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-kilobits-sec', 'kilobits/sec'), + id: 'Kbits', + fn: SIPrefix('b/s', 1), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-mebibytes-sec', 'mebibytes/sec'), + id: 'MiBs', + fn: binaryPrefix('B/s', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-mebibits-sec', 'mebibits/sec'), + id: 'Mibits', + fn: binaryPrefix('b/s', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-megabytes-sec', 'megabytes/sec'), + id: 'MBs', + fn: SIPrefix('B/s', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-megabits-sec', 'megabits/sec'), + id: 'Mbits', + fn: SIPrefix('b/s', 2), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-gibibytes-sec', 'gibibytes/sec'), + id: 'GiBs', + fn: binaryPrefix('B/s', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-gibibits-sec', 'gibibits/sec'), + id: 'Gibits', + fn: binaryPrefix('b/s', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-gigabytes-sec', 'gigabytes/sec'), + id: 'GBs', + fn: SIPrefix('B/s', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-gigabits-sec', 'gigabits/sec'), + id: 'Gbits', + fn: SIPrefix('b/s', 3), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-tebibytes-sec', 'tebibytes/sec'), + id: 'TiBs', + fn: binaryPrefix('B/s', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-tebibits-sec', 'tebibits/sec'), + id: 'Tibits', + fn: binaryPrefix('b/s', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-terabytes-sec', 'terabytes/sec'), + id: 'TBs', + fn: SIPrefix('B/s', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-terabits-sec', 'terabits/sec'), + id: 'Tbits', + fn: SIPrefix('b/s', 4), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-pebibytes-sec', 'pebibytes/sec'), + id: 'PiBs', + fn: binaryPrefix('B/s', 5), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-pebibits-sec', 'pebibits/sec'), + id: 'Pibits', + fn: binaryPrefix('b/s', 5), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-petabytes-sec', 'petabytes/sec'), + id: 'PBs', + fn: SIPrefix('B/s', 5), + }, + { + name: t('grafana-data.valueFormats.categories.data-rate.formats.name-petabits-sec', 'petabits/sec'), + id: 'Pbits', + fn: SIPrefix('b/s', 5), + }, + ], + }, + { + name: t('grafana-data.valueFormats.categories.date-time.name', 'Date & time'), + formats: [ + { + name: t('grafana-data.valueFormats.categories.date-time.formats.name-datetime-iso', 'Datetime ISO'), + id: 'dateTimeAsIso', + fn: dateTimeAsIso, + }, + { + name: t( + 'grafana-data.valueFormats.categories.date-time.formats.name-datetime-iso-no-date', + 'Datetime ISO (No date if today)' + ), + id: 'dateTimeAsIsoNoDateIfToday', + fn: dateTimeAsIsoNoDateIfToday, + }, + { + name: t('grafana-data.valueFormats.categories.date-time.formats.name-datetime-us', 'Datetime US'), + id: 'dateTimeAsUS', + fn: dateTimeAsUS, + }, + { + name: t( + 'grafana-data.valueFormats.categories.date-time.formats.name-datetime-us-no-date', + 'Datetime US (No date if today)' + ), + id: 'dateTimeAsUSNoDateIfToday', + fn: dateTimeAsUSNoDateIfToday, + }, + { + name: t('grafana-data.valueFormats.categories.date-time.formats.name-datetime-local', 'Datetime local'), + id: 'dateTimeAsLocal', + fn: getDateTimeAsLocalFormat(), + }, + { + name: t( + 'grafana-data.valueFormats.categories.date-time.formats.name-datetime-local-no-date', + 'Datetime local (No date if today)' + ), id: 'dateTimeAsLocalNoDateIfToday', fn: getDateTimeAsLocalFormatNoDateIfToday(), }, - { name: 'Datetime default', id: 'dateTimeAsSystem', fn: dateTimeSystemFormatter }, - { name: 'From Now', id: 'dateTimeFromNow', fn: dateTimeFromNow }, + { + name: t('grafana-data.valueFormats.categories.date-time.formats.name-datetime-default', 'Datetime default'), + id: 'dateTimeAsSystem', + fn: dateTimeSystemFormatter, + }, + { + name: t('grafana-data.valueFormats.categories.date-time.formats.name-from-now', 'From Now'), + id: 'dateTimeFromNow', + fn: dateTimeFromNow, + }, ], }, { - name: 'Energy', + name: t('grafana-data.valueFormats.categories.energy.name', 'Energy'), formats: [ - { name: 'Watt (W)', id: 'watt', fn: SIPrefix('W') }, - { name: 'Kilowatt (kW)', id: 'kwatt', fn: SIPrefix('W', 1) }, - { name: 'Megawatt (MW)', id: 'megwatt', fn: SIPrefix('W', 2) }, - { name: 'Gigawatt (GW)', id: 'gwatt', fn: SIPrefix('W', 3) }, - { name: 'Milliwatt (mW)', id: 'mwatt', fn: SIPrefix('W', -1) }, - { name: 'Watt per square meter (W/m²)', id: 'Wm2', fn: SIPrefix('W/m²') }, - { name: 'Volt-Ampere (VA)', id: 'voltamp', fn: SIPrefix('VA') }, - { name: 'Kilovolt-Ampere (kVA)', id: 'kvoltamp', fn: SIPrefix('VA', 1) }, - { name: 'Volt-Ampere reactive (VAr)', id: 'voltampreact', fn: SIPrefix('VAr') }, - { name: 'Kilovolt-Ampere reactive (kVAr)', id: 'kvoltampreact', fn: SIPrefix('VAr', 1) }, - { name: 'Watt-hour (Wh)', id: 'watth', fn: SIPrefix('Wh') }, - { name: 'Watt-hour per Kilogram (Wh/kg)', id: 'watthperkg', fn: SIPrefix('Wh/kg') }, - { name: 'Kilowatt-hour (kWh)', id: 'kwatth', fn: SIPrefix('Wh', 1) }, - { name: 'Kilowatt-min (kWm)', id: 'kwattm', fn: SIPrefix('W-Min', 1) }, - { name: 'Megawatt-hour (MWh)', id: 'mwatth', fn: SIPrefix('Wh', 2) }, - { name: 'Ampere-hour (Ah)', id: 'amph', fn: SIPrefix('Ah') }, - { name: 'Kiloampere-hour (kAh)', id: 'kamph', fn: SIPrefix('Ah', 1) }, - { name: 'Milliampere-hour (mAh)', id: 'mamph', fn: SIPrefix('Ah', -1) }, - { name: 'Joule (J)', id: 'joule', fn: SIPrefix('J') }, - { name: 'Electron volt (eV)', id: 'ev', fn: SIPrefix('eV') }, - { name: 'Ampere (A)', id: 'amp', fn: SIPrefix('A') }, - { name: 'Kiloampere (kA)', id: 'kamp', fn: SIPrefix('A', 1) }, - { name: 'Milliampere (mA)', id: 'mamp', fn: SIPrefix('A', -1) }, - { name: 'Volt (V)', id: 'volt', fn: SIPrefix('V') }, - { name: 'Kilovolt (kV)', id: 'kvolt', fn: SIPrefix('V', 1) }, - { name: 'Millivolt (mV)', id: 'mvolt', fn: SIPrefix('V', -1) }, - { name: 'Decibel-milliwatt (dBm)', id: 'dBm', fn: SIPrefix('dBm') }, - { name: 'Milliohm (mΩ)', id: 'mohm', fn: SIPrefix('Ω', -1) }, - { name: 'Ohm (Ω)', id: 'ohm', fn: SIPrefix('Ω') }, - { name: 'Kiloohm (kΩ)', id: 'kohm', fn: SIPrefix('Ω', 1) }, - { name: 'Megaohm (MΩ)', id: 'Mohm', fn: SIPrefix('Ω', 2) }, - { name: 'Farad (F)', id: 'farad', fn: SIPrefix('F') }, - { name: 'Microfarad (µF)', id: 'µfarad', fn: SIPrefix('F', -2) }, - { name: 'Nanofarad (nF)', id: 'nfarad', fn: SIPrefix('F', -3) }, - { name: 'Picofarad (pF)', id: 'pfarad', fn: SIPrefix('F', -4) }, - { name: 'Femtofarad (fF)', id: 'ffarad', fn: SIPrefix('F', -5) }, - { name: 'Henry (H)', id: 'henry', fn: SIPrefix('H') }, - { name: 'Millihenry (mH)', id: 'mhenry', fn: SIPrefix('H', -1) }, - { name: 'Microhenry (µH)', id: 'µhenry', fn: SIPrefix('H', -2) }, - { name: 'Lumens (Lm)', id: 'lumens', fn: SIPrefix('Lm') }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-watt', 'Watt (W)'), + id: 'watt', + fn: SIPrefix('W'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kilowatt', 'Kilowatt (kW)'), + id: 'kwatt', + fn: SIPrefix('W', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-megawatt', 'Megawatt (MW)'), + id: 'megwatt', + fn: SIPrefix('W', 2), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-gigawatt', 'Gigawatt (GW)'), + id: 'gwatt', + fn: SIPrefix('W', 3), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-milliwatt', 'Milliwatt (mW)'), + id: 'mwatt', + fn: SIPrefix('W', -1), + }, + { + name: t( + 'grafana-data.valueFormats.categories.energy.formats.name-watt-square-meter', + 'Watt per square meter (W/m²)' + ), + id: 'Wm2', + fn: SIPrefix('W/m²'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-volt-ampere', 'Volt-Ampere (VA)'), + id: 'voltamp', + fn: SIPrefix('VA'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kilovolt-ampere', 'Kilovolt-Ampere (kVA)'), + id: 'kvoltamp', + fn: SIPrefix('VA', 1), + }, + { + name: t( + 'grafana-data.valueFormats.categories.energy.formats.name-volt-ampere-reactive', + 'Volt-Ampere reactive (VAr)' + ), + id: 'voltampreact', + fn: SIPrefix('VAr'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.energy.formats.name-kilovolt-ampere-reactive', + 'Kilovolt-Ampere reactive (kVAr)' + ), + id: 'kvoltampreact', + fn: SIPrefix('VAr', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-watt-hour', 'Watt-hour (Wh)'), + id: 'watth', + fn: SIPrefix('Wh'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.energy.formats.name-watt-hour-per-kg', + 'Watt-hour per Kilogram (Wh/kg)' + ), + id: 'watthperkg', + fn: SIPrefix('Wh/kg'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kilowatt-hour', 'Kilowatt-hour (kWh)'), + id: 'kwatth', + fn: SIPrefix('Wh', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kilowatt-min', 'Kilowatt-min (kWm)'), + id: 'kwattm', + fn: SIPrefix('W-Min', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-megawatt-hour', 'Megawatt-hour (MWh)'), + id: 'mwatth', + fn: SIPrefix('Wh', 2), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-ampere-hour', 'Ampere-hour (Ah)'), + id: 'amph', + fn: SIPrefix('Ah'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kiloampere-hour', 'Kiloampere-hour (kAh)'), + id: 'kamph', + fn: SIPrefix('Ah', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-milliampere-hour', 'Milliampere-hour (mAh)'), + id: 'mamph', + fn: SIPrefix('Ah', -1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-joule', 'Joule (J)'), + id: 'joule', + fn: SIPrefix('J'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-electron-volt', 'Electron volt (eV)'), + id: 'ev', + fn: SIPrefix('eV'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-ampere', 'Ampere (A)'), + id: 'amp', + fn: SIPrefix('A'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kiloampere', 'Kiloampere (kA)'), + id: 'kamp', + fn: SIPrefix('A', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-milliampere', 'Milliampere (mA)'), + id: 'mamp', + fn: SIPrefix('A', -1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-volt', 'Volt (V)'), + id: 'volt', + fn: SIPrefix('V'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kilovolt', 'Kilovolt (kV)'), + id: 'kvolt', + fn: SIPrefix('V', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-millivolt', 'Millivolt (mV)'), + id: 'mvolt', + fn: SIPrefix('V', -1), + }, + { + name: t( + 'grafana-data.valueFormats.categories.energy.formats.name-decibel-milliwatt', + 'Decibel-milliwatt (dBm)' + ), + id: 'dBm', + fn: SIPrefix('dBm'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-milliohm', 'Milliohm (mΩ)'), + id: 'mohm', + fn: SIPrefix('Ω', -1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-ohm', 'Ohm (Ω)'), + id: 'ohm', + fn: SIPrefix('Ω'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-kiloohm', 'Kiloohm (kΩ)'), + id: 'kohm', + fn: SIPrefix('Ω', 1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-megaohm', 'Megaohm (MΩ)'), + id: 'Mohm', + fn: SIPrefix('Ω', 2), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-farad', 'Farad (F)'), + id: 'farad', + fn: SIPrefix('F'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-microfarad', 'Microfarad (µF)'), + id: 'µfarad', + fn: SIPrefix('F', -2), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-nanofarad', 'Nanofarad (nF)'), + id: 'nfarad', + fn: SIPrefix('F', -3), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-picofarad', 'Picofarad (pF)'), + id: 'pfarad', + fn: SIPrefix('F', -4), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-femtofarad', 'Femtofarad (fF)'), + id: 'ffarad', + fn: SIPrefix('F', -5), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-henry', 'Henry (H)'), + id: 'henry', + fn: SIPrefix('H'), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-millihenry', 'Millihenry (mH)'), + id: 'mhenry', + fn: SIPrefix('H', -1), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-microhenry', 'Microhenry (µH)'), + id: 'µhenry', + fn: SIPrefix('H', -2), + }, + { + name: t('grafana-data.valueFormats.categories.energy.formats.name-lumens', 'Lumens (Lm)'), + id: 'lumens', + fn: SIPrefix('Lm'), + }, ], }, { - name: 'Flow', + name: t('grafana-data.valueFormats.categories.flow.name', 'Flow'), formats: [ - { name: 'Gallons/min (gpm)', id: 'flowgpm', fn: toFixedUnit('gpm') }, - { name: 'Cubic meters/sec (cms)', id: 'flowcms', fn: toFixedUnit('cms') }, - { name: 'Cubic feet/sec (cfs)', id: 'flowcfs', fn: toFixedUnit('cfs') }, - { name: 'Cubic feet/min (cfm)', id: 'flowcfm', fn: toFixedUnit('cfm') }, - { name: 'Litre/hour', id: 'litreh', fn: toFixedUnit('L/h') }, - { name: 'Litre/min (L/min)', id: 'flowlpm', fn: toFixedUnit('L/min') }, - { name: 'milliLitre/min (mL/min)', id: 'flowmlpm', fn: toFixedUnit('mL/min') }, - { name: 'Lux (lx)', id: 'lux', fn: toFixedUnit('lux') }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-gallons-min', 'Gallons/min (gpm)'), + id: 'flowgpm', + fn: toFixedUnit('gpm'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-cubic-meters-sec', 'Cubic meters/sec (cms)'), + id: 'flowcms', + fn: toFixedUnit('cms'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-cubic-feet-sec', 'Cubic feet/sec (cfs)'), + id: 'flowcfs', + fn: toFixedUnit('cfs'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-cubic-feet-min', 'Cubic feet/min (cfm)'), + id: 'flowcfm', + fn: toFixedUnit('cfm'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-litre-hour', 'Litre/hour'), + id: 'litreh', + fn: toFixedUnit('L/h'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-litre-min', 'Litre/min (L/min)'), + id: 'flowlpm', + fn: toFixedUnit('L/min'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-millilitre-min', 'milliLitre/min (mL/min)'), + id: 'flowmlpm', + fn: toFixedUnit('mL/min'), + }, + { + name: t('grafana-data.valueFormats.categories.flow.formats.name-lux', 'Lux (lx)'), + id: 'lux', + fn: toFixedUnit('lux'), + }, ], }, { - name: 'Force', + name: t('grafana-data.valueFormats.categories.force.name', 'Force'), formats: [ - { name: 'Newton-meters (Nm)', id: 'forceNm', fn: SIPrefix('Nm') }, - { name: 'Kilonewton-meters (kNm)', id: 'forcekNm', fn: SIPrefix('Nm', 1) }, - { name: 'Newtons (N)', id: 'forceN', fn: SIPrefix('N') }, - { name: 'Kilonewtons (kN)', id: 'forcekN', fn: SIPrefix('N', 1) }, + { + name: t('grafana-data.valueFormats.categories.force.formats.name-newton-meters', 'Newton-meters (Nm)'), + id: 'forceNm', + fn: SIPrefix('Nm'), + }, + { + name: t('grafana-data.valueFormats.categories.force.formats.name-kilonewton-meters', 'Kilonewton-meters (kNm)'), + id: 'forcekNm', + fn: SIPrefix('Nm', 1), + }, + { + name: t('grafana-data.valueFormats.categories.force.formats.name-newtons', 'Newtons (N)'), + id: 'forceN', + fn: SIPrefix('N'), + }, + { + name: t('grafana-data.valueFormats.categories.force.formats.name-kilonewtons', 'Kilonewtons (kN)'), + id: 'forcekN', + fn: SIPrefix('N', 1), + }, ], }, { - name: 'Hash rate', + name: t('grafana-data.valueFormats.categories.hash-rate.name', 'Hash rate'), formats: [ - { name: 'hashes/sec', id: 'Hs', fn: SIPrefix('H/s') }, - { name: 'kilohashes/sec', id: 'KHs', fn: SIPrefix('H/s', 1) }, - { name: 'megahashes/sec', id: 'MHs', fn: SIPrefix('H/s', 2) }, - { name: 'gigahashes/sec', id: 'GHs', fn: SIPrefix('H/s', 3) }, - { name: 'terahashes/sec', id: 'THs', fn: SIPrefix('H/s', 4) }, - { name: 'petahashes/sec', id: 'PHs', fn: SIPrefix('H/s', 5) }, - { name: 'exahashes/sec', id: 'EHs', fn: SIPrefix('H/s', 6) }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-hashes-sec', 'hashes/sec'), + id: 'Hs', + fn: SIPrefix('H/s'), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-kilohashes-sec', 'kilohashes/sec'), + id: 'KHs', + fn: SIPrefix('H/s', 1), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-megahashes-sec', 'megahashes/sec'), + id: 'MHs', + fn: SIPrefix('H/s', 2), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-gigahashes-sec', 'gigahashes/sec'), + id: 'GHs', + fn: SIPrefix('H/s', 3), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-terahashes-sec', 'terahashes/sec'), + id: 'THs', + fn: SIPrefix('H/s', 4), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-petahashes-sec', 'petahashes/sec'), + id: 'PHs', + fn: SIPrefix('H/s', 5), + }, + { + name: t('grafana-data.valueFormats.categories.hash-rate.formats.name-exahashes-sec', 'exahashes/sec'), + id: 'EHs', + fn: SIPrefix('H/s', 6), + }, ], }, { - name: 'Mass', + name: t('grafana-data.valueFormats.categories.mass.name', 'Mass'), formats: [ - { name: 'milligram (mg)', id: 'massmg', fn: SIPrefix('g', -1) }, - { name: 'gram (g)', id: 'massg', fn: SIPrefix('g') }, - { name: 'pound (lb)', id: 'masslb', fn: toFixedUnit('lb') }, - { name: 'kilogram (kg)', id: 'masskg', fn: SIPrefix('g', 1) }, - { name: 'metric ton (t)', id: 'masst', fn: toFixedUnit('t') }, + { + name: t('grafana-data.valueFormats.categories.mass.formats.name-milligram', 'milligram (mg)'), + id: 'massmg', + fn: SIPrefix('g', -1), + }, + { + name: t('grafana-data.valueFormats.categories.mass.formats.name-gram', 'gram (g)'), + id: 'massg', + fn: SIPrefix('g'), + }, + { + name: t('grafana-data.valueFormats.categories.mass.formats.name-pound', 'pound (lb)'), + id: 'masslb', + fn: toFixedUnit('lb'), + }, + { + name: t('grafana-data.valueFormats.categories.mass.formats.name-kilogram', 'kilogram (kg)'), + id: 'masskg', + fn: SIPrefix('g', 1), + }, + { + name: t('grafana-data.valueFormats.categories.mass.formats.name-metric-ton', 'metric ton (t)'), + id: 'masst', + fn: toFixedUnit('t'), + }, ], }, { - name: 'Length', + name: t('grafana-data.valueFormats.categories.length.name', 'Length'), formats: [ - { name: 'millimeter (mm)', id: 'lengthmm', fn: SIPrefix('m', -1) }, - { name: 'inch (in)', id: 'lengthin', fn: toFixedUnit('in') }, - { name: 'feet (ft)', id: 'lengthft', fn: toFixedUnit('ft') }, - { name: 'meter (m)', id: 'lengthm', fn: SIPrefix('m') }, - { name: 'kilometer (km)', id: 'lengthkm', fn: SIPrefix('m', 1) }, - { name: 'mile (mi)', id: 'lengthmi', fn: toFixedUnit('mi') }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-millimeter', 'millimeter (mm)'), + id: 'lengthmm', + fn: SIPrefix('m', -1), + }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-inch', 'inch (in)'), + id: 'lengthin', + fn: toFixedUnit('in'), + }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-feet', 'feet (ft)'), + id: 'lengthft', + fn: toFixedUnit('ft'), + }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-meter', 'meter (m)'), + id: 'lengthm', + fn: SIPrefix('m'), + }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-kilometer', 'kilometer (km)'), + id: 'lengthkm', + fn: SIPrefix('m', 1), + }, + { + name: t('grafana-data.valueFormats.categories.length.formats.name-mile', 'mile (mi)'), + id: 'lengthmi', + fn: toFixedUnit('mi'), + }, ], }, { - name: 'Pressure', + name: t('grafana-data.valueFormats.categories.pressure.name', 'Pressure'), formats: [ - { name: 'Millibars', id: 'pressurembar', fn: SIPrefix('bar', -1) }, - { name: 'Bars', id: 'pressurebar', fn: SIPrefix('bar') }, - { name: 'Kilobars', id: 'pressurekbar', fn: SIPrefix('bar', 1) }, - { name: 'Pascals', id: 'pressurepa', fn: SIPrefix('Pa') }, - { name: 'Hectopascals', id: 'pressurehpa', fn: toFixedUnit('hPa') }, - { name: 'Kilopascals', id: 'pressurekpa', fn: toFixedUnit('kPa') }, - { name: 'Inches of mercury', id: 'pressurehg', fn: toFixedUnit('"Hg') }, - { name: 'PSI', id: 'pressurepsi', fn: scaledUnits(1000, ['psi', 'ksi', 'Mpsi']) }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-millibars', 'Millibars'), + id: 'pressurembar', + fn: SIPrefix('bar', -1), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-bars', 'Bars'), + id: 'pressurebar', + fn: SIPrefix('bar'), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-kilobars', 'Kilobars'), + id: 'pressurekbar', + fn: SIPrefix('bar', 1), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-pascals', 'Pascals'), + id: 'pressurepa', + fn: SIPrefix('Pa'), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-hectopascals', 'Hectopascals'), + id: 'pressurehpa', + fn: toFixedUnit('hPa'), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-kilopascals', 'Kilopascals'), + id: 'pressurekpa', + fn: toFixedUnit('kPa'), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-inches-mercury', 'Inches of mercury'), + id: 'pressurehg', + fn: toFixedUnit('"Hg'), + }, + { + name: t('grafana-data.valueFormats.categories.pressure.formats.name-psi', 'PSI'), + id: 'pressurepsi', + fn: scaledUnits(1000, ['psi', 'ksi', 'Mpsi']), + }, ], }, { - name: 'Radiation', + name: t('grafana-data.valueFormats.categories.radiation.name', 'Radiation'), formats: [ - { name: 'Becquerel (Bq)', id: 'radbq', fn: SIPrefix('Bq') }, - { name: 'curie (Ci)', id: 'radci', fn: SIPrefix('Ci') }, - { name: 'Gray (Gy)', id: 'radgy', fn: SIPrefix('Gy') }, - { name: 'rad', id: 'radrad', fn: SIPrefix('rad') }, - { name: 'Sievert (Sv)', id: 'radsv', fn: SIPrefix('Sv') }, - { name: 'milliSievert (mSv)', id: 'radmsv', fn: SIPrefix('Sv', -1) }, - { name: 'microSievert (µSv)', id: 'radusv', fn: SIPrefix('Sv', -2) }, - { name: 'rem', id: 'radrem', fn: SIPrefix('rem') }, - { name: 'Exposure (C/kg)', id: 'radexpckg', fn: SIPrefix('C/kg') }, - { name: 'roentgen (R)', id: 'radr', fn: SIPrefix('R') }, - { name: 'Sievert/hour (Sv/h)', id: 'radsvh', fn: SIPrefix('Sv/h') }, - { name: 'milliSievert/hour (mSv/h)', id: 'radmsvh', fn: SIPrefix('Sv/h', -1) }, - { name: 'microSievert/hour (µSv/h)', id: 'radusvh', fn: SIPrefix('Sv/h', -2) }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-becquerel', 'Becquerel (Bq)'), + id: 'radbq', + fn: SIPrefix('Bq'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-curie', 'curie (Ci)'), + id: 'radci', + fn: SIPrefix('Ci'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-gray', 'Gray (Gy)'), + id: 'radgy', + fn: SIPrefix('Gy'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-rad', 'rad'), + id: 'radrad', + fn: SIPrefix('rad'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-sievert', 'Sievert (Sv)'), + id: 'radsv', + fn: SIPrefix('Sv'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-millisievert', 'milliSievert (mSv)'), + id: 'radmsv', + fn: SIPrefix('Sv', -1), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-microsievert', 'microSievert (µSv)'), + id: 'radusv', + fn: SIPrefix('Sv', -2), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-rem', 'rem'), + id: 'radrem', + fn: SIPrefix('rem'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-exposure', 'Exposure (C/kg)'), + id: 'radexpckg', + fn: SIPrefix('C/kg'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-roentgen', 'roentgen (R)'), + id: 'radr', + fn: SIPrefix('R'), + }, + { + name: t('grafana-data.valueFormats.categories.radiation.formats.name-sievert-hour', 'Sievert/hour (Sv/h)'), + id: 'radsvh', + fn: SIPrefix('Sv/h'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.radiation.formats.name-millisievert-hour', + 'milliSievert/hour (mSv/h)' + ), + id: 'radmsvh', + fn: SIPrefix('Sv/h', -1), + }, + { + name: t( + 'grafana-data.valueFormats.categories.radiation.formats.name-microsievert-hour', + 'microSievert/hour (µSv/h)' + ), + id: 'radusvh', + fn: SIPrefix('Sv/h', -2), + }, ], }, { - name: 'Rotational Speed', + name: t('grafana-data.valueFormats.categories.rotational-speed.name', 'Rotational Speed'), formats: [ - { name: 'Revolutions per minute (rpm)', id: 'rotrpm', fn: toFixedUnit('rpm') }, - { name: 'Hertz (Hz)', id: 'rothz', fn: SIPrefix('Hz') }, - { name: 'Kilohertz (kHz)', id: 'rotkhz', fn: SIPrefix('Hz', 1) }, - { name: 'Megahertz (MHz)', id: 'rotmhz', fn: SIPrefix('Hz', 2) }, - { name: 'Gigahertz (GHz)', id: 'rotghz', fn: SIPrefix('Hz', 3) }, - { name: 'Radians per second (rad/s)', id: 'rotrads', fn: toFixedUnit('rad/s') }, - { name: 'Degrees per second (°/s)', id: 'rotdegs', fn: toFixedUnit('°/s') }, + { + name: t( + 'grafana-data.valueFormats.categories.rotational-speed.formats.name-rpm', + 'Revolutions per minute (rpm)' + ), + id: 'rotrpm', + fn: toFixedUnit('rpm'), + }, + { + name: t('grafana-data.valueFormats.categories.rotational-speed.formats.name-hertz', 'Hertz (Hz)'), + id: 'rothz', + fn: SIPrefix('Hz'), + }, + { + name: t('grafana-data.valueFormats.categories.rotational-speed.formats.name-kilohertz', 'Kilohertz (kHz)'), + id: 'rotkhz', + fn: SIPrefix('Hz', 1), + }, + { + name: t('grafana-data.valueFormats.categories.rotational-speed.formats.name-megahertz', 'Megahertz (MHz)'), + id: 'rotmhz', + fn: SIPrefix('Hz', 2), + }, + { + name: t('grafana-data.valueFormats.categories.rotational-speed.formats.name-gigahertz', 'Gigahertz (GHz)'), + id: 'rotghz', + fn: SIPrefix('Hz', 3), + }, + { + name: t( + 'grafana-data.valueFormats.categories.rotational-speed.formats.name-radians-sec', + 'Radians per second (rad/s)' + ), + id: 'rotrads', + fn: toFixedUnit('rad/s'), + }, + { + name: t( + 'grafana-data.valueFormats.categories.rotational-speed.formats.name-degrees-sec', + 'Degrees per second (°/s)' + ), + id: 'rotdegs', + fn: toFixedUnit('°/s'), + }, ], }, { - name: 'Temperature', + name: t('grafana-data.valueFormats.categories.temperature.name', 'Temperature'), formats: [ - { name: 'Celsius (°C)', id: 'celsius', fn: toFixedUnit('°C') }, - { name: 'Fahrenheit (°F)', id: 'fahrenheit', fn: toFixedUnit('°F') }, - { name: 'Kelvin (K)', id: 'kelvin', fn: toFixedUnit('K') }, + { + name: t('grafana-data.valueFormats.categories.temperature.formats.name-celsius', 'Celsius (°C)'), + id: 'celsius', + fn: toFixedUnit('°C'), + }, + { + name: t('grafana-data.valueFormats.categories.temperature.formats.name-fahrenheit', 'Fahrenheit (°F)'), + id: 'fahrenheit', + fn: toFixedUnit('°F'), + }, + { + name: t('grafana-data.valueFormats.categories.temperature.formats.name-kelvin', 'Kelvin (K)'), + id: 'kelvin', + fn: toFixedUnit('K'), + }, ], }, { - name: 'Time', + name: t('grafana-data.valueFormats.categories.time.name', 'Time'), formats: [ - { name: 'Hertz (1/s)', id: 'hertz', fn: SIPrefix('Hz') }, - { name: 'nanoseconds (ns)', id: 'ns', fn: toNanoSeconds }, - { name: 'microseconds (µs)', id: 'µs', fn: toMicroSeconds }, - { name: 'milliseconds (ms)', id: 'ms', fn: toMilliSeconds }, - { name: 'seconds (s)', id: 's', fn: toSeconds }, - { name: 'minutes (m)', id: 'm', fn: toMinutes }, - { name: 'hours (h)', id: 'h', fn: toHours }, - { name: 'days (d)', id: 'd', fn: toDays }, - { name: 'duration (ms)', id: 'dtdurationms', fn: toDurationInMilliseconds }, - { name: 'duration (s)', id: 'dtdurations', fn: toDurationInSeconds }, - { name: 'duration (hh:mm:ss)', id: 'dthms', fn: toDurationInHoursMinutesSeconds }, - { name: 'duration (d hh:mm:ss)', id: 'dtdhms', fn: toDurationInDaysHoursMinutesSeconds }, - { name: 'Timeticks (s/100)', id: 'timeticks', fn: toTimeTicks }, - { name: 'clock (ms)', id: 'clockms', fn: toClockMilliseconds }, - { name: 'clock (s)', id: 'clocks', fn: toClockSeconds }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-hertz', 'Hertz (1/s)'), + id: 'hertz', + fn: SIPrefix('Hz'), + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-nanoseconds', 'nanoseconds (ns)'), + id: 'ns', + fn: toNanoSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-microseconds', 'microseconds (µs)'), + id: 'µs', + fn: toMicroSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-milliseconds', 'milliseconds (ms)'), + id: 'ms', + fn: toMilliSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-seconds', 'seconds (s)'), + id: 's', + fn: toSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-minutes', 'minutes (m)'), + id: 'm', + fn: toMinutes, + }, + { name: t('grafana-data.valueFormats.categories.time.formats.name-hours', 'hours (h)'), id: 'h', fn: toHours }, + { name: t('grafana-data.valueFormats.categories.time.formats.name-days', 'days (d)'), id: 'd', fn: toDays }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-duration-ms', 'duration (ms)'), + id: 'dtdurationms', + fn: toDurationInMilliseconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-duration-s', 'duration (s)'), + id: 'dtdurations', + fn: toDurationInSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-duration-hms', 'duration (hh:mm:ss)'), + id: 'dthms', + fn: toDurationInHoursMinutesSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-duration-dhms', 'duration (d hh:mm:ss)'), + id: 'dtdhms', + fn: toDurationInDaysHoursMinutesSeconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-timeticks', 'Timeticks (s/100)'), + id: 'timeticks', + fn: toTimeTicks, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-clock-ms', 'clock (ms)'), + id: 'clockms', + fn: toClockMilliseconds, + }, + { + name: t('grafana-data.valueFormats.categories.time.formats.name-clock-s', 'clock (s)'), + id: 'clocks', + fn: toClockSeconds, + }, ], }, { - name: 'Throughput', + name: t('grafana-data.valueFormats.categories.throughput.name', 'Throughput'), formats: [ - { name: 'counts/sec (cps)', id: 'cps', fn: simpleCountUnit('c/s') }, - { name: 'ops/sec (ops)', id: 'ops', fn: simpleCountUnit('ops/s') }, - { name: 'requests/sec (rps)', id: 'reqps', fn: simpleCountUnit('req/s') }, - { name: 'reads/sec (rps)', id: 'rps', fn: simpleCountUnit('rd/s') }, - { name: 'writes/sec (wps)', id: 'wps', fn: simpleCountUnit('wr/s') }, - { name: 'I/O ops/sec (iops)', id: 'iops', fn: simpleCountUnit('io/s') }, - { name: 'events/sec (eps)', id: 'eps', fn: simpleCountUnit('evt/s') }, - { name: 'messages/sec (mps)', id: 'mps', fn: simpleCountUnit('msg/s') }, - { name: 'records/sec (rps)', id: 'recps', fn: simpleCountUnit('rec/s') }, - { name: 'rows/sec (rps)', id: 'rowsps', fn: simpleCountUnit('rows/s') }, - { name: 'counts/min (cpm)', id: 'cpm', fn: simpleCountUnit('c/m') }, - { name: 'ops/min (opm)', id: 'opm', fn: simpleCountUnit('ops/m') }, - { name: 'requests/min (rpm)', id: 'reqpm', fn: simpleCountUnit('req/m') }, - { name: 'reads/min (rpm)', id: 'rpm', fn: simpleCountUnit('rd/m') }, - { name: 'writes/min (wpm)', id: 'wpm', fn: simpleCountUnit('wr/m') }, - { name: 'events/min (epm)', id: 'epm', fn: simpleCountUnit('evts/m') }, - { name: 'messages/min (mpm)', id: 'mpm', fn: simpleCountUnit('msgs/m') }, - { name: 'records/min (rpm)', id: 'recpm', fn: simpleCountUnit('rec/m') }, - { name: 'rows/min (rpm)', id: 'rowspm', fn: simpleCountUnit('rows/m') }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-counts-sec', 'counts/sec (cps)'), + id: 'cps', + fn: simpleCountUnit('c/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-ops-sec', 'ops/sec (ops)'), + id: 'ops', + fn: simpleCountUnit('ops/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-requests-sec', 'requests/sec (rps)'), + id: 'reqps', + fn: simpleCountUnit('req/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-reads-sec', 'reads/sec (rps)'), + id: 'rps', + fn: simpleCountUnit('rd/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-writes-sec', 'writes/sec (wps)'), + id: 'wps', + fn: simpleCountUnit('wr/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-io-ops-sec', 'I/O ops/sec (iops)'), + id: 'iops', + fn: simpleCountUnit('io/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-events-sec', 'events/sec (eps)'), + id: 'eps', + fn: simpleCountUnit('evt/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-messages-sec', 'messages/sec (mps)'), + id: 'mps', + fn: simpleCountUnit('msg/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-records-sec', 'records/sec (rps)'), + id: 'recps', + fn: simpleCountUnit('rec/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-rows-sec', 'rows/sec (rps)'), + id: 'rowsps', + fn: simpleCountUnit('rows/s'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-counts-min', 'counts/min (cpm)'), + id: 'cpm', + fn: simpleCountUnit('c/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-ops-min', 'ops/min (opm)'), + id: 'opm', + fn: simpleCountUnit('ops/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-requests-min', 'requests/min (rpm)'), + id: 'reqpm', + fn: simpleCountUnit('req/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-reads-min', 'reads/min (rpm)'), + id: 'rpm', + fn: simpleCountUnit('rd/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-writes-min', 'writes/min (wpm)'), + id: 'wpm', + fn: simpleCountUnit('wr/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-events-min', 'events/min (epm)'), + id: 'epm', + fn: simpleCountUnit('evts/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-messages-min', 'messages/min (mpm)'), + id: 'mpm', + fn: simpleCountUnit('msgs/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-records-min', 'records/min (rpm)'), + id: 'recpm', + fn: simpleCountUnit('rec/m'), + }, + { + name: t('grafana-data.valueFormats.categories.throughput.formats.name-rows-min', 'rows/min (rpm)'), + id: 'rowspm', + fn: simpleCountUnit('rows/m'), + }, ], }, { - name: 'Velocity', + name: t('grafana-data.valueFormats.categories.velocity.name', 'Velocity'), formats: [ - { name: 'meters/second (m/s)', id: 'velocityms', fn: toFixedUnit('m/s') }, - { name: 'kilometers/hour (km/h)', id: 'velocitykmh', fn: toFixedUnit('km/h') }, - { name: 'miles/hour (mph)', id: 'velocitymph', fn: toFixedUnit('mph') }, - { name: 'knot (kn)', id: 'velocityknot', fn: toFixedUnit('kn') }, + { + name: t('grafana-data.valueFormats.categories.velocity.formats.name-meters-second', 'meters/second (m/s)'), + id: 'velocityms', + fn: toFixedUnit('m/s'), + }, + { + name: t('grafana-data.valueFormats.categories.velocity.formats.name-kilometers-hour', 'kilometers/hour (km/h)'), + id: 'velocitykmh', + fn: toFixedUnit('km/h'), + }, + { + name: t('grafana-data.valueFormats.categories.velocity.formats.name-miles-hour', 'miles/hour (mph)'), + id: 'velocitymph', + fn: toFixedUnit('mph'), + }, + { + name: t('grafana-data.valueFormats.categories.velocity.formats.name-knot', 'knot (kn)'), + id: 'velocityknot', + fn: toFixedUnit('kn'), + }, ], }, { - name: 'Volume', + name: t('grafana-data.valueFormats.categories.volume.name', 'Volume'), formats: [ - { name: 'millilitre (mL)', id: 'mlitre', fn: SIPrefix('L', -1) }, - { name: 'litre (L)', id: 'litre', fn: SIPrefix('L') }, - { name: 'cubic meter', id: 'm3', fn: toFixedUnit('m³') }, - { name: 'Normal cubic meter', id: 'Nm3', fn: toFixedUnit('Nm³') }, - { name: 'cubic decimeter', id: 'dm3', fn: toFixedUnit('dm³') }, - { name: 'gallons', id: 'gallons', fn: toFixedUnit('gal') }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-millilitre', 'millilitre (mL)'), + id: 'mlitre', + fn: SIPrefix('L', -1), + }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-litre', 'litre (L)'), + id: 'litre', + fn: SIPrefix('L'), + }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-cubic-meter', 'cubic meter'), + id: 'm3', + fn: toFixedUnit('m³'), + }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-normal-cubic-meter', 'Normal cubic meter'), + id: 'Nm3', + fn: toFixedUnit('Nm³'), + }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-cubic-decimeter', 'cubic decimeter'), + id: 'dm3', + fn: toFixedUnit('dm³'), + }, + { + name: t('grafana-data.valueFormats.categories.volume.formats.name-gallons', 'gallons'), + id: 'gallons', + fn: toFixedUnit('gal'), + }, ], }, { - name: 'Boolean', + name: t('grafana-data.valueFormats.categories.boolean.name', 'Boolean'), formats: [ - { name: 'True / False', id: 'bool', fn: booleanValueFormatter('True', 'False') }, - { name: 'Yes / No', id: 'bool_yes_no', fn: booleanValueFormatter('Yes', 'No') }, - { name: 'On / Off', id: 'bool_on_off', fn: booleanValueFormatter('On', 'Off') }, + { + name: t('grafana-data.valueFormats.categories.boolean.formats.name-true-false', 'True / False'), + id: 'bool', + fn: booleanValueFormatter('True', 'False'), + }, + { + name: t('grafana-data.valueFormats.categories.boolean.formats.name-yes-no', 'Yes / No'), + id: 'bool_yes_no', + fn: booleanValueFormatter('Yes', 'No'), + }, + { + name: t('grafana-data.valueFormats.categories.boolean.formats.name-on-off', 'On / Off'), + id: 'bool_on_off', + fn: booleanValueFormatter('On', 'Off'), + }, ], }, ]; diff --git a/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.test.ts b/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.test.ts index 88303e2503b..e6df676beba 100644 --- a/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.test.ts +++ b/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.test.ts @@ -1,7 +1,7 @@ import { config } from '@grafana/runtime'; import { SUGGESTIONS_LIMIT } from '../../../constants'; -import { FUNCTIONS } from '../../../promql'; +import { getFunctions } from '../../../promql'; import { getMockTimeRange } from '../../../test/mocks/datasource'; import { filterMetricNames, getCompletions } from './completions'; @@ -172,7 +172,7 @@ const metricNameCompletionSituations = ['AT_ROOT', 'IN_FUNCTION', 'EMPTY'] as Me function getSuggestionCountForSituation(situationType: MetricNameSituation, metricsCount: number): number { const limitedMetricNamesCount = metricsCount < SUGGESTIONS_LIMIT ? metricsCount : SUGGESTIONS_LIMIT; - let suggestionsCount = limitedMetricNamesCount + FUNCTIONS.length; + let suggestionsCount = limitedMetricNamesCount + getFunctions().length; if (situationType === 'EMPTY') { suggestionsCount += history.length; diff --git a/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.ts b/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.ts index def4cd7eaaa..f7fc08f8bce 100644 --- a/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.ts +++ b/packages/grafana-prometheus/src/components/monaco-query-field/monaco-completion-provider/completions.ts @@ -6,7 +6,7 @@ import { TimeRange } from '@grafana/data'; import { config } from '@grafana/runtime'; import { escapeLabelValueInExactSelector, prometheusRegularEscape } from '../../../escaping'; -import { FUNCTIONS } from '../../../promql'; +import { getFunctions } from '../../../promql'; import { isValidLegacyName } from '../../../utf8_support'; import { DataProvider } from './data_provider'; @@ -100,18 +100,20 @@ function getAllMetricNamesCompletions(dataProvider: DataProvider): Completion[] })); } -const FUNCTION_COMPLETIONS: Completion[] = FUNCTIONS.map((f) => ({ - type: 'FUNCTION', - label: f.label, - insertText: f.insertText ?? '', // i don't know what to do when this is nullish. it should not be. - detail: f.detail, - documentation: f.documentation, -})); +const getFunctionCompletions: () => Completion[] = () => { + return getFunctions().map((f) => ({ + type: 'FUNCTION', + label: f.label, + insertText: f.insertText ?? '', // i don't know what to do when this is nullish. it should not be. + detail: f.detail, + documentation: f.documentation, + })); +}; async function getAllFunctionsAndMetricNamesCompletions(dataProvider: DataProvider): Promise { const metricNames = getAllMetricNamesCompletions(dataProvider); - return [...FUNCTION_COMPLETIONS, ...metricNames]; + return [...getFunctionCompletions(), ...metricNames]; } const DURATION_COMPLETIONS: Completion[] = [ @@ -276,7 +278,7 @@ export function getCompletions( case 'EMPTY': { const metricNames = getAllMetricNamesCompletions(dataProvider); const historyCompletions = getAllHistoryCompletions(dataProvider); - return Promise.resolve([...historyCompletions, ...FUNCTION_COMPLETIONS, ...metricNames]); + return Promise.resolve([...historyCompletions, ...getFunctionCompletions(), ...metricNames]); } case 'IN_LABEL_SELECTOR_NO_LABEL_NAME': return getLabelNamesForSelectorCompletions(situation.metricName, situation.otherLabels, dataProvider, timeRange); diff --git a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json index 26fecb50168..85eba24f8a4 100644 --- a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json +++ b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json @@ -209,6 +209,103 @@ "label-verbose": "Verbose" } }, + "promql": { + "getAggregationOptions": { + "documentation-avg": "Calculate the average over dimensions", + "documentation-bottomk": "Smallest k elements by sample value", + "documentation-count": "Count number of elements in the vector", + "documentation-count-values": "Count number of elements with the same value", + "documentation-group": "All values in the resulting vector are 1", + "documentation-max": "Select maximum over dimensions", + "documentation-min": "Select minimum over dimensions", + "documentation-quantile": "Calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions", + "documentation-stddev": "Calculate population standard deviation over dimensions", + "documentation-stdvar": "Calculate population standard variance over dimensions", + "documentation-sum": "Calculate sum over dimensions", + "documentation-topk": "Largest k elements by sample value" + }, + "getFunctions": { + "documentation-abs": "Returns the input vector with all sample values converted to their absolute value.", + "documentation-absent": "Returns an empty vector if the vector passed to it has any elements and a 1-element vector with the value 1 if the vector passed to it has no elements. This is useful for alerting on when no time series exist for a given metric name and label combination.", + "documentation-absent-over-time": "Returns an empty vector if the range vector passed to it has any elements and a 1-element vector with the value 1 if the range vector passed to it has no elements.", + "documentation-avg-over-time": "The average value of all points in the specified interval.", + "documentation-ceil": "Rounds the sample values of all elements in `v` up to the nearest integer.", + "documentation-changes": "For each input time series, `changes(v range-vector)` returns the number of times its value has changed within the provided time range as an instant vector.", + "documentation-clamp": "Clamps the sample values of all elements in `v` to have a lower limit of `min` and an upper limit of `max`.", + "documentation-clamp-max": "Clamps the sample values of all elements in `v` to have an upper limit of `max`.", + "documentation-clamp-min": "Clamps the sample values of all elements in `v` to have a lower limit of `min`.", + "documentation-count-over-time": "The count of all values in the specified interval.", + "documentation-count-scalar": "Returns the number of elements in a time series vector as a scalar. This is in contrast to the `count()` aggregation operator, which always returns a vector (an empty one if the input vector is empty) and allows grouping by labels via a `by` clause.", + "documentation-day-of-month": "Returns the day of the month for each of the given times in UTC. Returned values are from 1 to 31.", + "documentation-day-of-week": "Returns the day of the week for each of the given times in UTC. Returned values are from 0 to 6, where 0 means Sunday etc.", + "documentation-day-of-year": "Returns the day of the year for each of the given times in UTC. Returned values are from 1 to 365 for non-leap years, and 1 to 366 in leap years.", + "documentation-days-in-month": "Returns number of days in the month for each of the given times in UTC. Returned values are from 28 to 31.", + "documentation-deg": "Converts radians to degrees for all elements in v", + "documentation-delta": "Calculates the difference between the first and last value of each time series element in a range vector `v`, returning an instant vector with the given deltas and equivalent labels. The delta is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if the sample values are all integers.", + "documentation-deriv": "Calculates the per-second derivative of the time series in a range vector `v`, using simple linear regression.", + "documentation-double-exponential-smoothing": "Produces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.", + "documentation-drop-common-labels": "Drops all labels that have the same name and value across all series in the input vector.", + "documentation-exp": "Calculates the exponential function for all elements in `v`.\nSpecial cases are:\n* `Exp(+Inf) = +Inf` \n* `Exp(NaN) = NaN`", + "documentation-floor": "Rounds the sample values of all elements in `v` down to the nearest integer.", + "documentation-histogram-avg": "Returns the arithmetic average of observed values stored in a native histogram. Samples that are not native histograms are ignored and do not show up in the returned vector.", + "documentation-histogram-count": "Returns the count of observations stored in a native histogram.", + "documentation-histogram-fraction": "Returns the estimated fraction of observations between the provided lower and upper values.", + "documentation-histogram-quantile": "Calculates the φ-quantile (0 ≤ φ ≤ 1) from the buckets `b` of a histogram. The samples in `b` are the counts of observations in each bucket. Each sample must have a label `le` where the label value denotes the inclusive upper bound of the bucket. (Samples without such a label are silently ignored.) The histogram metric type automatically provides time series with the `_bucket` suffix and the appropriate labels.", + "documentation-histogram-stddev": "Returns the estimated standard deviation of observations in a native histogram, based on the geometric mean of the buckets where the observations lie.", + "documentation-histogram-stdvar": "Returns the estimated standard variance of observations in a native histogram.", + "documentation-histogram-sum": "Returns the sum of observations stored in a native histogram.", + "documentation-holt-winters": "Renamed as double_exponential_smoothing in prometheus v3.x. For prometheus versions equal and greater than v3.0 please use double_exponential_smoothing. \n\nProduces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.", + "documentation-hour": "Returns the hour of the day for each of the given times in UTC. Returned values are from 0 to 23.", + "documentation-idelta": "Calculates the difference between the last two samples in the range vector `v`, returning an instant vector with the given deltas and equivalent labels.", + "documentation-increase": "Calculates the increase in the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. The increase is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if a counter increases only by integer increments.", + "documentation-info": "Returns latest details and metadata about a group of metrics, such as their labels and current values, without doing any calculations", + "documentation-irate": "Calculates the per-second instant rate of increase of the time series in the range vector. This is based on the last two data points. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for.", + "documentation-label-join": "For each timeseries in `v`, joins all the values of all the `src_labels` using `separator` and returns the timeseries with the label `dst_label` containing the joined value. There can be any number of `src_labels` in this function.", + "documentation-label-replace": "For each timeseries in `v`, `label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)` matches the regular expression `regex` against the label `src_label`. If it matches, then the timeseries is returned with the label `dst_label` replaced by the expansion of `replacement`. `$1` is replaced with the first matching subgroup, `$2` with the second etc. If the regular expression doesn't match then the timeseries is returned unchanged.", + "documentation-last-over-time": "The most recent point value in specified interval.", + "documentation-ln": "Calculates the natural logarithm for all elements in `v`.\nSpecial cases are:\n * `ln(+Inf) = +Inf`\n * `ln(0) = -Inf`\n * `ln(x < 0) = NaN`\n * `ln(NaN) = NaN`", + "documentation-log10": "Calculates the decimal logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.", + "documentation-log2": "Calculates the binary logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.", + "documentation-max-over-time": "The maximum value of all points in the specified interval.", + "documentation-min-over-time": "The minimum value of all points in the specified interval.", + "documentation-minute": "Returns the minute of the hour for each of the given times in UTC. Returned values are from 0 to 59.", + "documentation-month": "Returns the month of the year for each of the given times in UTC. Returned values are from 1 to 12, where 1 means January etc.", + "documentation-pi": "Returns pi", + "documentation-predict-linear": "Predicts the value of time series `t` seconds from now, based on the range vector `v`, using simple linear regression.", + "documentation-present-over-time": "The value 1 for any series in the specified interval.", + "documentation-quantile-over-time": "The φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.", + "documentation-rad": "Converts degrees to radians for all elements in v", + "documentation-rate": "Calculates the per-second average rate of increase of the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. Also, the calculation extrapolates to the ends of the time range, allowing for missed scrapes or imperfect alignment of scrape cycles with the range's time period.", + "documentation-resets": "For each input time series, `resets(v range-vector)` returns the number of counter resets within the provided time range as an instant vector. Any decrease in the value between two consecutive samples is interpreted as a counter reset.", + "documentation-round": "Rounds the sample values of all elements in `v` to the nearest integer. Ties are resolved by rounding up. The optional `to_nearest` argument allows specifying the nearest multiple to which the sample values should be rounded. This multiple may also be a fraction.", + "documentation-scalar": "Given a single-element input vector, `scalar(v instant-vector)` returns the sample value of that single element as a scalar. If the input vector does not have exactly one element, `scalar` will return `NaN`.", + "documentation-sgn": "Returns a vector with all sample values converted to their sign, defined as this: 1 if v is positive, -1 if v is negative and 0 if v is equal to zero.", + "documentation-sort": "Returns vector elements sorted by their sample values, in ascending order.", + "documentation-sort-desc": "Returns vector elements sorted by their sample values, in descending order.", + "documentation-sqrt": "Calculates the square root of all elements in `v`.", + "documentation-stddev-over-time": "The population standard deviation of the values in the specified interval.", + "documentation-stdvar-over-time": "The population standard variance of the values in the specified interval.", + "documentation-sum-over-time": "The sum of all values in the specified interval.", + "documentation-time": "Returns the number of seconds since January 1, 1970 UTC. Note that this does not actually return the current time, but the time at which the expression is to be evaluated.", + "documentation-timestamp": "Returns the timestamp of each of the samples of the given vector as the number of seconds since January 1, 1970 UTC.", + "documentation-vector": "Returns the scalar `s` as a vector with no labels.", + "documentation-year": "Returns the year for each of the given times in UTC." + }, + "getTrigonometricFunctions": { + "documentation-acos": "calculates the arccosine of all elements in {{argument}}", + "documentation-acosh": "calculates the inverse hyperbolic cosine of all elements in {{argument}}", + "documentation-asin": "calculates the arcsine of all elements in {{argument}}", + "documentation-asinh": "calculates the inverse hyperbolic sine of all elements in {{argument}}", + "documentation-atan": "calculates the arctangent of all elements in {{argument}}", + "documentation-atanh": "calculates the inverse hyperbolic tangent of all elements in {{argument}}", + "documentation-cos": "calculates the cosine of all elements in {{argument}}", + "documentation-cosh": "calculates the hyperbolic cosine of all elements in {{argument}}", + "documentation-sin": "calculates the sine of all elements in {{argument}}", + "documentation-sinh": "calculates the hyperbolic sine of all elements in {{argument}}", + "documentation-tan": "calculates the tangent of all elements in {{argument}}", + "documentation-tanh": "calculates the hyperbolic tangent of all elements in {{argument}}" + } + }, "querybuilder": { "additional-settings": { "content-filter-metric-names-regex-search-using": "Filter metric names by regex search, using an additional call on the Prometheus API.", @@ -319,6 +416,13 @@ "title-add": "Add {{name}}", "title-remove": "Remove {{name}}" }, + "operation-utils": { + "getAggregationExplainer": { + "label-by": "Calculates {{aggregationName}} over dimensions while preserving {{labelWord}} {{labels}}.", + "label-default": "Calculates {{aggregationName}} over the dimensions.", + "label-without": "Calculates {{aggregationName}} over the dimensions {{labels}}. All other labels are preserved." + } + }, "prom-query-builder-options": { "aria-label-lower-limit-parameter": "Set lower limit for the step parameter", "aria-label-select-resolution": "Select resolution", diff --git a/packages/grafana-prometheus/src/promql.ts b/packages/grafana-prometheus/src/promql.ts index 9235777c6a5..d3e6304312b 100644 --- a/packages/grafana-prometheus/src/promql.ts +++ b/packages/grafana-prometheus/src/promql.ts @@ -1,577 +1,819 @@ // Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/promql.ts import { Grammar } from 'prismjs'; +import { t } from '@grafana/i18n'; import { CompletionItem } from '@grafana/ui'; export const OPERATORS = ['by', 'group_left', 'group_right', 'ignoring', 'on', 'offset', 'without']; export const LOGICAL_OPERATORS = ['or', 'and', 'unless']; -const TRIGONOMETRIC_FUNCTIONS: CompletionItem[] = [ +const getTrigonometricFunctions: () => CompletionItem[] = () => [ { label: 'acos', insertText: 'acos', detail: 'acos(v instant-vector)', - documentation: 'calculates the arccosine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-acos', + 'calculates the arccosine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'acosh', insertText: 'acosh', detail: 'acosh(v instant-vector)', - documentation: 'calculates the inverse hyperbolic cosine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-acosh', + 'calculates the inverse hyperbolic cosine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'asin', insertText: 'asin', detail: 'asin(v instant-vector)', - documentation: 'calculates the arcsine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-asin', + 'calculates the arcsine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'asinh', insertText: 'asinh', detail: 'asinh(v instant-vector)', - documentation: 'calculates the inverse hyperbolic sine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-asinh', + 'calculates the inverse hyperbolic sine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'atan', insertText: 'atan', detail: 'atan(v instant-vector)', - documentation: 'calculates the arctangent of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-atan', + 'calculates the arctangent of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'atanh', insertText: 'atanh', detail: 'atanh(v instant-vector)', - documentation: 'calculates the inverse hyperbolic tangent of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-atanh', + 'calculates the inverse hyperbolic tangent of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'cos', insertText: 'cos', detail: 'cos(v instant-vector)', - documentation: 'calculates the cosine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-cos', + 'calculates the cosine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'cosh', insertText: 'cosh', detail: 'cosh(v instant-vector)', - documentation: 'calculates the hyperbolic cosine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-cosh', + 'calculates the hyperbolic cosine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'sin', insertText: 'sin', detail: 'sin(v instant-vector)', - documentation: 'calculates the sine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-sin', + 'calculates the sine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'sinh', insertText: 'sinh', detail: 'sinh(v instant-vector)', - documentation: 'calculates the hyperbolic sine of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-sinh', + 'calculates the hyperbolic sine of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'tan', insertText: 'tan', detail: 'tan(v instant-vector)', - documentation: 'calculates the tangent of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-tan', + 'calculates the tangent of all elements in {{argument}}', + { argument: 'v' } + ), }, { label: 'tanh', insertText: 'tanh', detail: 'tanh(v instant-vector)', - documentation: 'calculates the hyperbolic tangent of all elements in v', + documentation: t( + 'grafana-prometheus.promql.getTrigonometricFunctions.documentation-tanh', + 'calculates the hyperbolic tangent of all elements in {{argument}}', + { argument: 'v' } + ), }, ]; -const AGGREGATION_OPERATORS: CompletionItem[] = [ +const getAggregationOptions: () => CompletionItem[] = () => [ { label: 'sum', insertText: 'sum', - documentation: 'Calculate sum over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-sum', + 'Calculate sum over dimensions' + ), }, { label: 'min', insertText: 'min', - documentation: 'Select minimum over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-min', + 'Select minimum over dimensions' + ), }, { label: 'max', insertText: 'max', - documentation: 'Select maximum over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-max', + 'Select maximum over dimensions' + ), }, { label: 'avg', insertText: 'avg', - documentation: 'Calculate the average over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-avg', + 'Calculate the average over dimensions' + ), }, { label: 'group', insertText: 'group', - documentation: 'All values in the resulting vector are 1', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-group', + 'All values in the resulting vector are 1' + ), }, { label: 'stddev', insertText: 'stddev', - documentation: 'Calculate population standard deviation over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-stddev', + 'Calculate population standard deviation over dimensions' + ), }, { label: 'stdvar', insertText: 'stdvar', - documentation: 'Calculate population standard variance over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-stdvar', + 'Calculate population standard variance over dimensions' + ), }, { label: 'count', insertText: 'count', - documentation: 'Count number of elements in the vector', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-count', + 'Count number of elements in the vector' + ), }, { label: 'count_values', insertText: 'count_values', - documentation: 'Count number of elements with the same value', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-count-values', + 'Count number of elements with the same value' + ), }, { label: 'bottomk', insertText: 'bottomk', - documentation: 'Smallest k elements by sample value', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-bottomk', + 'Smallest k elements by sample value' + ), }, { label: 'topk', insertText: 'topk', - documentation: 'Largest k elements by sample value', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-topk', + 'Largest k elements by sample value' + ), }, { label: 'quantile', insertText: 'quantile', - documentation: 'Calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions', + documentation: t( + 'grafana-prometheus.promql.getAggregationOptions.documentation-quantile', + 'Calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions' + ), }, ]; -export const FUNCTIONS = [ - ...AGGREGATION_OPERATORS, - ...TRIGONOMETRIC_FUNCTIONS, +export const getFunctions = () => [ + ...getAggregationOptions(), + ...getTrigonometricFunctions(), { insertText: 'abs', label: 'abs', detail: 'abs(v instant-vector)', - documentation: 'Returns the input vector with all sample values converted to their absolute value.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-abs', + 'Returns the input vector with all sample values converted to their absolute value.' + ), }, { insertText: 'absent', label: 'absent', detail: 'absent(v instant-vector)', - documentation: - 'Returns an empty vector if the vector passed to it has any elements and a 1-element vector with the value 1 if the vector passed to it has no elements. This is useful for alerting on when no time series exist for a given metric name and label combination.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-absent', + 'Returns an empty vector if the vector passed to it has any elements and a 1-element vector with the value 1 if the vector passed to it has no elements. This is useful for alerting on when no time series exist for a given metric name and label combination.' + ), }, { insertText: 'absent_over_time', label: 'absent_over_time', detail: 'absent(v range-vector)', - documentation: - 'Returns an empty vector if the range vector passed to it has any elements and a 1-element vector with the value 1 if the range vector passed to it has no elements.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-absent-over-time', + 'Returns an empty vector if the range vector passed to it has any elements and a 1-element vector with the value 1 if the range vector passed to it has no elements.' + ), }, { insertText: 'ceil', label: 'ceil', detail: 'ceil(v instant-vector)', - documentation: 'Rounds the sample values of all elements in `v` up to the nearest integer.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-ceil', + 'Rounds the sample values of all elements in `v` up to the nearest integer.' + ), }, { insertText: 'changes', label: 'changes', detail: 'changes(v range-vector)', - documentation: - 'For each input time series, `changes(v range-vector)` returns the number of times its value has changed within the provided time range as an instant vector.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-changes', + 'For each input time series, `changes(v range-vector)` returns the number of times its value has changed within the provided time range as an instant vector.' + ), }, { insertText: 'clamp', label: 'clamp', detail: 'clamp(v instant-vector, min scalar, max scalar)', - documentation: - 'Clamps the sample values of all elements in `v` to have a lower limit of `min` and an upper limit of `max`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-clamp', + 'Clamps the sample values of all elements in `v` to have a lower limit of `min` and an upper limit of `max`.' + ), }, { insertText: 'clamp_max', label: 'clamp_max', detail: 'clamp_max(v instant-vector, max scalar)', - documentation: 'Clamps the sample values of all elements in `v` to have an upper limit of `max`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-clamp-max', + 'Clamps the sample values of all elements in `v` to have an upper limit of `max`.' + ), }, { insertText: 'clamp_min', label: 'clamp_min', detail: 'clamp_min(v instant-vector, min scalar)', - documentation: 'Clamps the sample values of all elements in `v` to have a lower limit of `min`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-clamp-min', + 'Clamps the sample values of all elements in `v` to have a lower limit of `min`.' + ), }, { insertText: 'count_scalar', label: 'count_scalar', detail: 'count_scalar(v instant-vector)', - documentation: - 'Returns the number of elements in a time series vector as a scalar. This is in contrast to the `count()` aggregation operator, which always returns a vector (an empty one if the input vector is empty) and allows grouping by labels via a `by` clause.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-count-scalar', + 'Returns the number of elements in a time series vector as a scalar. This is in contrast to the `count()` aggregation operator, which always returns a vector (an empty one if the input vector is empty) and allows grouping by labels via a `by` clause.' + ), }, { insertText: 'deg', label: 'deg', detail: 'deg(v instant-vector)', - documentation: 'Converts radians to degrees for all elements in v', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-deg', + 'Converts radians to degrees for all elements in v' + ), }, { insertText: 'day_of_month', label: 'day_of_month', detail: 'day_of_month(v=vector(time()) instant-vector)', - documentation: 'Returns the day of the month for each of the given times in UTC. Returned values are from 1 to 31.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-day-of-month', + 'Returns the day of the month for each of the given times in UTC. Returned values are from 1 to 31.' + ), }, { insertText: 'day_of_week', label: 'day_of_week', detail: 'day_of_week(v=vector(time()) instant-vector)', - documentation: - 'Returns the day of the week for each of the given times in UTC. Returned values are from 0 to 6, where 0 means Sunday etc.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-day-of-week', + 'Returns the day of the week for each of the given times in UTC. Returned values are from 0 to 6, where 0 means Sunday etc.' + ), }, { insertText: 'day_of_year', label: 'day_of_year', detail: 'day_of_year(v=vector(time()) instant-vector)', - documentation: - 'Returns the day of the year for each of the given times in UTC. Returned values are from 1 to 365 for non-leap years, and 1 to 366 in leap years.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-day-of-year', + 'Returns the day of the year for each of the given times in UTC. Returned values are from 1 to 365 for non-leap years, and 1 to 366 in leap years.' + ), }, { insertText: 'days_in_month', label: 'days_in_month', detail: 'days_in_month(v=vector(time()) instant-vector)', - documentation: - 'Returns number of days in the month for each of the given times in UTC. Returned values are from 28 to 31.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-days-in-month', + 'Returns number of days in the month for each of the given times in UTC. Returned values are from 28 to 31.' + ), }, { insertText: 'delta', label: 'delta', detail: 'delta(v range-vector)', - documentation: - 'Calculates the difference between the first and last value of each time series element in a range vector `v`, returning an instant vector with the given deltas and equivalent labels. The delta is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if the sample values are all integers.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-delta', + 'Calculates the difference between the first and last value of each time series element in a range vector `v`, returning an instant vector with the given deltas and equivalent labels. The delta is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if the sample values are all integers.' + ), }, { insertText: 'deriv', label: 'deriv', detail: 'deriv(v range-vector)', - documentation: - 'Calculates the per-second derivative of the time series in a range vector `v`, using simple linear regression.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-deriv', + 'Calculates the per-second derivative of the time series in a range vector `v`, using simple linear regression.' + ), }, { insertText: 'double_exponential_smoothing', label: 'double_exponential_smoothing', detail: 'double_exponential_smoothing(v range-vector, sf scalar, tf scalar)', - documentation: - 'Produces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-double-exponential-smoothing', + 'Produces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.' + ), }, { insertText: 'drop_common_labels', label: 'drop_common_labels', detail: 'drop_common_labels(instant-vector)', - documentation: 'Drops all labels that have the same name and value across all series in the input vector.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-drop-common-labels', + 'Drops all labels that have the same name and value across all series in the input vector.' + ), }, { insertText: 'exp', label: 'exp', detail: 'exp(v instant-vector)', - documentation: - 'Calculates the exponential function for all elements in `v`.\nSpecial cases are:\n* `Exp(+Inf) = +Inf` \n* `Exp(NaN) = NaN`', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-exp', + 'Calculates the exponential function for all elements in `v`.\nSpecial cases are:\n* `Exp(+Inf) = +Inf` \n* `Exp(NaN) = NaN`' + ), }, { insertText: 'floor', label: 'floor', detail: 'floor(v instant-vector)', - documentation: 'Rounds the sample values of all elements in `v` down to the nearest integer.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-floor', + 'Rounds the sample values of all elements in `v` down to the nearest integer.' + ), }, { insertText: 'histogram_quantile', label: 'histogram_quantile', detail: 'histogram_quantile(φ float, b instant-vector)', - documentation: - 'Calculates the φ-quantile (0 ≤ φ ≤ 1) from the buckets `b` of a histogram. The samples in `b` are the counts of observations in each bucket. Each sample must have a label `le` where the label value denotes the inclusive upper bound of the bucket. (Samples without such a label are silently ignored.) The histogram metric type automatically provides time series with the `_bucket` suffix and the appropriate labels.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-quantile', + 'Calculates the φ-quantile (0 ≤ φ ≤ 1) from the buckets `b` of a histogram. The samples in `b` are the counts of observations in each bucket. Each sample must have a label `le` where the label value denotes the inclusive upper bound of the bucket. (Samples without such a label are silently ignored.) The histogram metric type automatically provides time series with the `_bucket` suffix and the appropriate labels.' + ), }, { insertText: 'holt_winters', label: 'holt_winters', detail: 'holt_winters(v range-vector, sf scalar, tf scalar)', - documentation: - 'Renamed as double_exponential_smoothing in prometheus v3.x. For prometheus versions equal and greater than v3.0 please use double_exponential_smoothing. \n\nProduces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-holt-winters', + 'Renamed as double_exponential_smoothing in prometheus v3.x. For prometheus versions equal and greater than v3.0 please use double_exponential_smoothing. \n\nProduces a smoothed value for time series based on the range in `v`. The lower the smoothing factor `sf`, the more importance is given to old data. The higher the trend factor `tf`, the more trends in the data is considered. Both `sf` and `tf` must be between 0 and 1.' + ), }, { insertText: 'hour', label: 'hour', detail: 'hour(v=vector(time()) instant-vector)', - documentation: 'Returns the hour of the day for each of the given times in UTC. Returned values are from 0 to 23.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-hour', + 'Returns the hour of the day for each of the given times in UTC. Returned values are from 0 to 23.' + ), }, { insertText: 'idelta', label: 'idelta', detail: 'idelta(v range-vector)', - documentation: - 'Calculates the difference between the last two samples in the range vector `v`, returning an instant vector with the given deltas and equivalent labels.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-idelta', + 'Calculates the difference between the last two samples in the range vector `v`, returning an instant vector with the given deltas and equivalent labels.' + ), }, { insertText: 'increase', label: 'increase', detail: 'increase(v range-vector)', - documentation: - 'Calculates the increase in the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. The increase is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if a counter increases only by integer increments.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-increase', + 'Calculates the increase in the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. The increase is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if a counter increases only by integer increments.' + ), }, { insertText: 'info', label: 'info', detail: 'info(v instant-vector, [data-label-selector instant-vector])', - documentation: - 'Returns latest details and metadata about a group of metrics, such as their labels and current values, without doing any calculations', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-info', + 'Returns latest details and metadata about a group of metrics, such as their labels and current values, without doing any calculations' + ), }, { insertText: 'irate', label: 'irate', detail: 'irate(v range-vector)', - documentation: - 'Calculates the per-second instant rate of increase of the time series in the range vector. This is based on the last two data points. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-irate', + 'Calculates the per-second instant rate of increase of the time series in the range vector. This is based on the last two data points. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for.' + ), }, { insertText: 'label_join', label: 'label_join', detail: 'label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)', - documentation: - 'For each timeseries in `v`, joins all the values of all the `src_labels` using `separator` and returns the timeseries with the label `dst_label` containing the joined value. There can be any number of `src_labels` in this function.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-label-join', + 'For each timeseries in `v`, joins all the values of all the `src_labels` using `separator` and returns the timeseries with the label `dst_label` containing the joined value. There can be any number of `src_labels` in this function.' + ), }, { insertText: 'label_replace', label: 'label_replace', detail: 'label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)', - documentation: - "For each timeseries in `v`, `label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)` matches the regular expression `regex` against the label `src_label`. If it matches, then the timeseries is returned with the label `dst_label` replaced by the expansion of `replacement`. `$1` is replaced with the first matching subgroup, `$2` with the second etc. If the regular expression doesn't match then the timeseries is returned unchanged.", + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-label-replace', + "For each timeseries in `v`, `label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)` matches the regular expression `regex` against the label `src_label`. If it matches, then the timeseries is returned with the label `dst_label` replaced by the expansion of `replacement`. `$1` is replaced with the first matching subgroup, `$2` with the second etc. If the regular expression doesn't match then the timeseries is returned unchanged." + ), }, { insertText: 'ln', label: 'ln', detail: 'ln(v instant-vector)', - documentation: - 'Calculates the natural logarithm for all elements in `v`.\nSpecial cases are:\n * `ln(+Inf) = +Inf`\n * `ln(0) = -Inf`\n * `ln(x < 0) = NaN`\n * `ln(NaN) = NaN`', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-ln', + 'Calculates the natural logarithm for all elements in `v`.\nSpecial cases are:\n * `ln(+Inf) = +Inf`\n * `ln(0) = -Inf`\n * `ln(x < 0) = NaN`\n * `ln(NaN) = NaN`' + ), }, { insertText: 'log2', label: 'log2', detail: 'log2(v instant-vector)', - documentation: - 'Calculates the binary logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-log2', + 'Calculates the binary logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.' + ), }, { insertText: 'log10', label: 'log10', detail: 'log10(v instant-vector)', - documentation: - 'Calculates the decimal logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-log10', + 'Calculates the decimal logarithm for all elements in `v`. The special cases are equivalent to those in `ln`.' + ), }, { insertText: 'minute', label: 'minute', detail: 'minute(v=vector(time()) instant-vector)', - documentation: - 'Returns the minute of the hour for each of the given times in UTC. Returned values are from 0 to 59.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-minute', + 'Returns the minute of the hour for each of the given times in UTC. Returned values are from 0 to 59.' + ), }, { insertText: 'month', label: 'month', detail: 'month(v=vector(time()) instant-vector)', - documentation: - 'Returns the month of the year for each of the given times in UTC. Returned values are from 1 to 12, where 1 means January etc.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-month', + 'Returns the month of the year for each of the given times in UTC. Returned values are from 1 to 12, where 1 means January etc.' + ), }, { insertText: 'pi', label: 'pi', detail: 'pi()', - documentation: 'Returns pi', + documentation: t('grafana-prometheus.promql.getFunctions.documentation-pi', 'Returns pi'), }, { insertText: 'predict_linear', label: 'predict_linear', detail: 'predict_linear(v range-vector, t scalar)', - documentation: - 'Predicts the value of time series `t` seconds from now, based on the range vector `v`, using simple linear regression.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-predict-linear', + 'Predicts the value of time series `t` seconds from now, based on the range vector `v`, using simple linear regression.' + ), }, { insertText: 'rad', label: 'rad', detail: 'rad(v instant-vector)', - documentation: 'Converts degrees to radians for all elements in v', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-rad', + 'Converts degrees to radians for all elements in v' + ), }, { insertText: 'rate', label: 'rate', detail: 'rate(v range-vector)', - documentation: - "Calculates the per-second average rate of increase of the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. Also, the calculation extrapolates to the ends of the time range, allowing for missed scrapes or imperfect alignment of scrape cycles with the range's time period.", + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-rate', + "Calculates the per-second average rate of increase of the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for. Also, the calculation extrapolates to the ends of the time range, allowing for missed scrapes or imperfect alignment of scrape cycles with the range's time period." + ), }, { insertText: 'resets', label: 'resets', detail: 'resets(v range-vector)', - documentation: - 'For each input time series, `resets(v range-vector)` returns the number of counter resets within the provided time range as an instant vector. Any decrease in the value between two consecutive samples is interpreted as a counter reset.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-resets', + 'For each input time series, `resets(v range-vector)` returns the number of counter resets within the provided time range as an instant vector. Any decrease in the value between two consecutive samples is interpreted as a counter reset.' + ), }, { insertText: 'round', label: 'round', detail: 'round(v instant-vector, to_nearest=1 scalar)', - documentation: - 'Rounds the sample values of all elements in `v` to the nearest integer. Ties are resolved by rounding up. The optional `to_nearest` argument allows specifying the nearest multiple to which the sample values should be rounded. This multiple may also be a fraction.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-round', + 'Rounds the sample values of all elements in `v` to the nearest integer. Ties are resolved by rounding up. The optional `to_nearest` argument allows specifying the nearest multiple to which the sample values should be rounded. This multiple may also be a fraction.' + ), }, { insertText: 'scalar', label: 'scalar', detail: 'scalar(v instant-vector)', - documentation: - 'Given a single-element input vector, `scalar(v instant-vector)` returns the sample value of that single element as a scalar. If the input vector does not have exactly one element, `scalar` will return `NaN`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-scalar', + 'Given a single-element input vector, `scalar(v instant-vector)` returns the sample value of that single element as a scalar. If the input vector does not have exactly one element, `scalar` will return `NaN`.' + ), }, { insertText: 'sgn', label: 'sgn', detail: 'sgn(v instant-vector)', - documentation: - 'Returns a vector with all sample values converted to their sign, defined as this: 1 if v is positive, -1 if v is negative and 0 if v is equal to zero.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-sgn', + 'Returns a vector with all sample values converted to their sign, defined as this: 1 if v is positive, -1 if v is negative and 0 if v is equal to zero.' + ), }, { insertText: 'sort', label: 'sort', detail: 'sort(v instant-vector)', - documentation: 'Returns vector elements sorted by their sample values, in ascending order.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-sort', + 'Returns vector elements sorted by their sample values, in ascending order.' + ), }, { insertText: 'sort_desc', label: 'sort_desc', detail: 'sort_desc(v instant-vector)', - documentation: 'Returns vector elements sorted by their sample values, in descending order.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-sort-desc', + 'Returns vector elements sorted by their sample values, in descending order.' + ), }, { insertText: 'sqrt', label: 'sqrt', detail: 'sqrt(v instant-vector)', - documentation: 'Calculates the square root of all elements in `v`.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-sqrt', + 'Calculates the square root of all elements in `v`.' + ), }, { insertText: 'time', label: 'time', detail: 'time()', - documentation: - 'Returns the number of seconds since January 1, 1970 UTC. Note that this does not actually return the current time, but the time at which the expression is to be evaluated.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-time', + 'Returns the number of seconds since January 1, 1970 UTC. Note that this does not actually return the current time, but the time at which the expression is to be evaluated.' + ), }, { insertText: 'timestamp', label: 'timestamp', detail: 'timestamp(v instant-vector)', - documentation: - 'Returns the timestamp of each of the samples of the given vector as the number of seconds since January 1, 1970 UTC.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-timestamp', + 'Returns the timestamp of each of the samples of the given vector as the number of seconds since January 1, 1970 UTC.' + ), }, { insertText: 'vector', label: 'vector', detail: 'vector(s scalar)', - documentation: 'Returns the scalar `s` as a vector with no labels.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-vector', + 'Returns the scalar `s` as a vector with no labels.' + ), }, { insertText: 'year', label: 'year', detail: 'year(v=vector(time()) instant-vector)', - documentation: 'Returns the year for each of the given times in UTC.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-year', + 'Returns the year for each of the given times in UTC.' + ), }, { insertText: 'avg_over_time', label: 'avg_over_time', detail: 'avg_over_time(range-vector)', - documentation: 'The average value of all points in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-avg-over-time', + 'The average value of all points in the specified interval.' + ), }, { insertText: 'min_over_time', label: 'min_over_time', detail: 'min_over_time(range-vector)', - documentation: 'The minimum value of all points in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-min-over-time', + 'The minimum value of all points in the specified interval.' + ), }, { insertText: 'max_over_time', label: 'max_over_time', detail: 'max_over_time(range-vector)', - documentation: 'The maximum value of all points in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-max-over-time', + 'The maximum value of all points in the specified interval.' + ), }, { insertText: 'sum_over_time', label: 'sum_over_time', detail: 'sum_over_time(range-vector)', - documentation: 'The sum of all values in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-sum-over-time', + 'The sum of all values in the specified interval.' + ), }, { insertText: 'count_over_time', label: 'count_over_time', detail: 'count_over_time(range-vector)', - documentation: 'The count of all values in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-count-over-time', + 'The count of all values in the specified interval.' + ), }, { insertText: 'quantile_over_time', label: 'quantile_over_time', detail: 'quantile_over_time(scalar, range-vector)', - documentation: 'The φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-quantile-over-time', + 'The φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.' + ), }, { insertText: 'stddev_over_time', label: 'stddev_over_time', detail: 'stddev_over_time(range-vector)', - documentation: 'The population standard deviation of the values in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-stddev-over-time', + 'The population standard deviation of the values in the specified interval.' + ), }, { insertText: 'stdvar_over_time', label: 'stdvar_over_time', detail: 'stdvar_over_time(range-vector)', - documentation: 'The population standard variance of the values in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-stdvar-over-time', + 'The population standard variance of the values in the specified interval.' + ), }, { insertText: 'last_over_time', label: 'last_over_time', detail: 'last_over_time(range-vector)', - documentation: 'The most recent point value in specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-last-over-time', + 'The most recent point value in specified interval.' + ), }, { insertText: 'present_over_time', label: 'present_over_time', detail: 'present_over_time(range-vector)', - documentation: 'The value 1 for any series in the specified interval.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-present-over-time', + 'The value 1 for any series in the specified interval.' + ), }, { insertText: 'histogram_avg', label: 'histogram_avg', detail: 'histogram_avg(v instant-vector)', - documentation: - 'Returns the arithmetic average of observed values stored in a native histogram. Samples that are not native histograms are ignored and do not show up in the returned vector.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-avg', + 'Returns the arithmetic average of observed values stored in a native histogram. Samples that are not native histograms are ignored and do not show up in the returned vector.' + ), }, { insertText: 'histogram_count', label: 'histogram_count', detail: 'histogram_count(v instant-vector)', - documentation: 'Returns the count of observations stored in a native histogram.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-count', + 'Returns the count of observations stored in a native histogram.' + ), }, { insertText: 'histogram_sum', label: 'histogram_sum', detail: 'histogram_sum(v instant-vector)', - documentation: 'Returns the sum of observations stored in a native histogram.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-sum', + 'Returns the sum of observations stored in a native histogram.' + ), }, { insertText: 'histogram_fraction', label: 'histogram_fraction', detail: 'histogram_fraction(lower scalar, upper scalar, v instant-vector)', - documentation: 'Returns the estimated fraction of observations between the provided lower and upper values.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-fraction', + 'Returns the estimated fraction of observations between the provided lower and upper values.' + ), }, { insertText: 'histogram_stddev', label: 'histogram_stddev', detail: 'histogram_stddev(v instant-vector)', - documentation: - 'Returns the estimated standard deviation of observations in a native histogram, based on the geometric mean of the buckets where the observations lie.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-stddev', + 'Returns the estimated standard deviation of observations in a native histogram, based on the geometric mean of the buckets where the observations lie.' + ), }, { insertText: 'histogram_stdvar', label: 'histogram_stdvar', detail: 'histogram_stdvar(v instant-vector)', - documentation: 'Returns the estimated standard variance of observations in a native histogram.', + documentation: t( + 'grafana-prometheus.promql.getFunctions.documentation-histogram-stdvar', + 'Returns the estimated standard variance of observations in a native histogram.' + ), }, ]; @@ -610,7 +852,12 @@ export const promqlGrammar: Grammar = { punctuation: /[{]/, }, }, - function: new RegExp(`\\b(?:${FUNCTIONS.map((f) => f.label).join('|')})(?=\\s*\\()`, 'i'), + function: new RegExp( + `\\b(?:${getFunctions() + .map((f) => f.label) + .join('|')})(?=\\s*\\()`, + 'i' + ), 'context-range': [ { pattern: /\[[^\]]*(?=])/, // [1m] diff --git a/packages/grafana-prometheus/src/querybuilder/PromQueryModeller.ts b/packages/grafana-prometheus/src/querybuilder/PromQueryModeller.ts index caf90017526..9286382d7eb 100644 --- a/packages/grafana-prometheus/src/querybuilder/PromQueryModeller.ts +++ b/packages/grafana-prometheus/src/querybuilder/PromQueryModeller.ts @@ -1,5 +1,5 @@ // Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/querybuilder/PromQueryModeller.ts -import { FUNCTIONS } from '../promql'; +import { getFunctions } from '../promql'; import { getAggregationOperations } from './aggregations'; import { getOperationDefinitions } from './operations'; @@ -16,7 +16,7 @@ export class PromQueryModeller extends PromQueryModellerBase implements PromQuer super(() => { const allOperations = [...getOperationDefinitions(), ...getAggregationOperations()]; for (const op of allOperations) { - const func = FUNCTIONS.find((x) => x.insertText === op.id); + const func = getFunctions().find((x) => x.insertText === op.id); if (func) { op.documentation = func.documentation; } diff --git a/packages/grafana-prometheus/src/querybuilder/operationUtils.ts b/packages/grafana-prometheus/src/querybuilder/operationUtils.ts index 00f9bc72b0c..227621b1734 100644 --- a/packages/grafana-prometheus/src/querybuilder/operationUtils.ts +++ b/packages/grafana-prometheus/src/querybuilder/operationUtils.ts @@ -3,6 +3,7 @@ import { capitalize } from 'lodash'; import pluralize from 'pluralize'; import { SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { QueryBuilderLabelFilter, @@ -265,11 +266,23 @@ export function getAggregationExplainer(aggregationName: string, mode: 'by' | 'w switch (mode) { case 'by': - return `Calculates ${aggregationName} over dimensions while preserving ${labelWord} ${labels}.`; + return t( + 'grafana-prometheus.querybuilder.operation-utils.getAggregationExplainer.label-by', + 'Calculates {{aggregationName}} over dimensions while preserving {{labelWord}} {{labels}}.', + { aggregationName, labelWord, labels } + ); case 'without': - return `Calculates ${aggregationName} over the dimensions ${labels}. All other labels are preserved.`; + return t( + 'grafana-prometheus.querybuilder.operation-utils.getAggregationExplainer.label-without', + 'Calculates {{aggregationName}} over the dimensions {{labels}}. All other labels are preserved.', + { aggregationName, labels } + ); default: - return `Calculates ${aggregationName} over the dimensions.`; + return t( + 'grafana-prometheus.querybuilder.operation-utils.getAggregationExplainer.label-default', + 'Calculates {{aggregationName}} over the dimensions.', + { aggregationName } + ); } }; } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index d689ec15261..2c009a575c4 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -7736,6 +7736,409 @@ } } }, + "grafana-data": { + "valueFormats": { + "categories": { + "acceleration": { + "formats": { + "name-feet-sec": "Feet/sec²", + "name-g-unit": "G unit", + "name-meters-sec": "Meters/sec²" + }, + "name": "Acceleration" + }, + "angle": { + "formats": { + "name-arc-minutes": "Arc Minutes", + "name-arc-seconds": "Arc Seconds", + "name-degrees": "Degrees (°)", + "name-gradian": "Gradian", + "name-radians": "Radians" + }, + "name": "Angle" + }, + "area": { + "formats": { + "name-acres": "Acres (ac)", + "name-hectares": "Hectares (ha)", + "name-square-feet": "Square Feet (ft²)", + "name-square-meters": "Square Meters (m²)", + "name-square-miles": "Square Miles (mi²)" + }, + "name": "Area" + }, + "boolean": { + "formats": { + "name-on-off": "On / Off", + "name-true-false": "True / False", + "name-yes-no": "Yes / No" + }, + "name": "Boolean" + }, + "computation": { + "formats": { + "name-eflops": "EFLOP/s", + "name-flops": "FLOP/s", + "name-gflops": "GFLOP/s", + "name-mflops": "MFLOP/s", + "name-pflops": "PFLOP/s", + "name-tflops": "TFLOP/s", + "name-yflops": "YFLOP/s", + "name-zflops": "ZFLOP/s" + }, + "name": "Computation" + }, + "concentration": { + "formats": { + "name-g-m3": "gram per cubic meter (g/m³)", + "name-g-nm3": "gram per normal cubic meter (g/Nm³)", + "name-mg-dl": "milligrams per decilitre (mg/dL)", + "name-mg-m3": "milligram per cubic meter (mg/m³)", + "name-mg-nm3": "milligram per normal cubic meter (mg/Nm³)", + "name-mmol-l": "millimoles per litre (mmol/L)", + "name-ng-m3": "nanogram per cubic meter (ng/m³)", + "name-ng-nm3": "nanogram per normal cubic meter (ng/Nm³)", + "name-ppb": "parts-per-billion (ppb)", + "name-ppm": "parts-per-million (ppm)", + "name-ug-m3": "microgram per cubic meter (μg/m³)", + "name-ug-nm3": "microgram per normal cubic meter (μg/Nm³)" + }, + "name": "Concentration" + }, + "currency": { + "formats": { + "name-bgn": "Bulgarian Lev (BGN)", + "name-brl": "Real (R$)", + "name-btc": "Bitcoin (฿)", + "name-chf": "Swiss franc (CHF)", + "name-czk": "Czech koruna (czk)", + "name-dkk": "Danish Krone (kr)", + "name-eur": "Euro (€)", + "name-gbp": "Pounds (£)", + "name-idr": "Indonesian Rupiah (Rp)", + "name-ils": "Israeli New Shekels (₪)", + "name-inr": "Indian Rupee (₹)", + "name-isk": "Icelandic Króna (kr)", + "name-jpy": "Yen (¥)", + "name-krw": "South Korean Won (₩)", + "name-mbtc": "Milli Bitcoin (฿)", + "name-myr": "Malaysian Ringgit (RM)", + "name-nok": "Norwegian Krone (kr)", + "name-php": "Philippine Peso (PHP)", + "name-pln": "Polish Złoty (PLN)", + "name-pyg": "Guaraní (₲)", + "name-rub": "Rubles (₽)", + "name-sek": "Swedish Krona (kr)", + "name-try": "Turkish Lira (₺)", + "name-uah": "Hryvnias (₴)", + "name-ubtc": "Micro Bitcoin (฿)", + "name-usd": "Dollars ($)", + "name-uyu": "Uruguay Peso (UYU)", + "name-vnd": "Vietnamese Dong (VND)", + "name-xpf": "CFP franc (XPF)", + "name-zar": "South African Rand (R)" + }, + "name": "Currency" + }, + "data": { + "formats": { + "name-bits-iec": "bits(IEC)", + "name-bits-si": "bits(SI)", + "name-bytes-iec": "bytes(IEC)", + "name-bytes-si": "bytes(SI)", + "name-gibibytes": "gibibytes", + "name-gigabytes": "gigabytes", + "name-kibibytes": "kibibytes", + "name-kilobytes": "kilobytes", + "name-mebibytes": "mebibytes", + "name-megabytes": "megabytes", + "name-pebibytes": "pebibytes", + "name-petabytes": "petabytes", + "name-tebibytes": "tebibytes", + "name-terabytes": "terabytes" + }, + "name": "Data" + }, + "data-rate": { + "formats": { + "name-bits-sec-iec": "bits/sec(IEC)", + "name-bits-sec-si": "bits/sec(SI)", + "name-bytes-sec-iec": "bytes/sec(IEC)", + "name-bytes-sec-si": "bytes/sec(SI)", + "name-gibibits-sec": "gibibits/sec", + "name-gibibytes-sec": "gibibytes/sec", + "name-gigabits-sec": "gigabits/sec", + "name-gigabytes-sec": "gigabytes/sec", + "name-kibibits-sec": "kibibits/sec", + "name-kibibytes-sec": "kibibytes/sec", + "name-kilobits-sec": "kilobits/sec", + "name-kilobytes-sec": "kilobytes/sec", + "name-mebibits-sec": "mebibits/sec", + "name-mebibytes-sec": "mebibytes/sec", + "name-megabits-sec": "megabits/sec", + "name-megabytes-sec": "megabytes/sec", + "name-packets-sec": "packets/sec", + "name-pebibits-sec": "pebibits/sec", + "name-pebibytes-sec": "pebibytes/sec", + "name-petabits-sec": "petabits/sec", + "name-petabytes-sec": "petabytes/sec", + "name-tebibits-sec": "tebibits/sec", + "name-tebibytes-sec": "tebibytes/sec", + "name-terabits-sec": "terabits/sec", + "name-terabytes-sec": "terabytes/sec" + }, + "name": "Data rate" + }, + "date-time": { + "formats": { + "name-datetime-default": "Datetime default", + "name-datetime-iso": "Datetime ISO", + "name-datetime-iso-no-date": "Datetime ISO (No date if today)", + "name-datetime-local": "Datetime local", + "name-datetime-local-no-date": "Datetime local (No date if today)", + "name-datetime-us": "Datetime US", + "name-datetime-us-no-date": "Datetime US (No date if today)", + "name-from-now": "From Now" + }, + "name": "Date & time" + }, + "energy": { + "formats": { + "name-ampere": "Ampere (A)", + "name-ampere-hour": "Ampere-hour (Ah)", + "name-decibel-milliwatt": "Decibel-milliwatt (dBm)", + "name-electron-volt": "Electron volt (eV)", + "name-farad": "Farad (F)", + "name-femtofarad": "Femtofarad (fF)", + "name-gigawatt": "Gigawatt (GW)", + "name-henry": "Henry (H)", + "name-joule": "Joule (J)", + "name-kiloampere": "Kiloampere (kA)", + "name-kiloampere-hour": "Kiloampere-hour (kAh)", + "name-kiloohm": "Kiloohm (kΩ)", + "name-kilovolt": "Kilovolt (kV)", + "name-kilovolt-ampere": "Kilovolt-Ampere (kVA)", + "name-kilovolt-ampere-reactive": "Kilovolt-Ampere reactive (kVAr)", + "name-kilowatt": "Kilowatt (kW)", + "name-kilowatt-hour": "Kilowatt-hour (kWh)", + "name-kilowatt-min": "Kilowatt-min (kWm)", + "name-lumens": "Lumens (Lm)", + "name-megaohm": "Megaohm (MΩ)", + "name-megawatt": "Megawatt (MW)", + "name-megawatt-hour": "Megawatt-hour (MWh)", + "name-microfarad": "Microfarad (µF)", + "name-microhenry": "Microhenry (µH)", + "name-milliampere": "Milliampere (mA)", + "name-milliampere-hour": "Milliampere-hour (mAh)", + "name-millihenry": "Millihenry (mH)", + "name-milliohm": "Milliohm (mΩ)", + "name-millivolt": "Millivolt (mV)", + "name-milliwatt": "Milliwatt (mW)", + "name-nanofarad": "Nanofarad (nF)", + "name-ohm": "Ohm (Ω)", + "name-picofarad": "Picofarad (pF)", + "name-volt": "Volt (V)", + "name-volt-ampere": "Volt-Ampere (VA)", + "name-volt-ampere-reactive": "Volt-Ampere reactive (VAr)", + "name-watt": "Watt (W)", + "name-watt-hour": "Watt-hour (Wh)", + "name-watt-hour-per-kg": "Watt-hour per Kilogram (Wh/kg)", + "name-watt-square-meter": "Watt per square meter (W/m²)" + }, + "name": "Energy" + }, + "flow": { + "formats": { + "name-cubic-feet-min": "Cubic feet/min (cfm)", + "name-cubic-feet-sec": "Cubic feet/sec (cfs)", + "name-cubic-meters-sec": "Cubic meters/sec (cms)", + "name-gallons-min": "Gallons/min (gpm)", + "name-litre-hour": "Litre/hour", + "name-litre-min": "Litre/min (L/min)", + "name-lux": "Lux (lx)", + "name-millilitre-min": "milliLitre/min (mL/min)" + }, + "name": "Flow" + }, + "force": { + "formats": { + "name-kilonewton-meters": "Kilonewton-meters (kNm)", + "name-kilonewtons": "Kilonewtons (kN)", + "name-newton-meters": "Newton-meters (Nm)", + "name-newtons": "Newtons (N)" + }, + "name": "Force" + }, + "hash-rate": { + "formats": { + "name-exahashes-sec": "exahashes/sec", + "name-gigahashes-sec": "gigahashes/sec", + "name-hashes-sec": "hashes/sec", + "name-kilohashes-sec": "kilohashes/sec", + "name-megahashes-sec": "megahashes/sec", + "name-petahashes-sec": "petahashes/sec", + "name-terahashes-sec": "terahashes/sec" + }, + "name": "Hash rate" + }, + "length": { + "formats": { + "name-feet": "feet (ft)", + "name-inch": "inch (in)", + "name-kilometer": "kilometer (km)", + "name-meter": "meter (m)", + "name-mile": "mile (mi)", + "name-millimeter": "millimeter (mm)" + }, + "name": "Length" + }, + "mass": { + "formats": { + "name-gram": "gram (g)", + "name-kilogram": "kilogram (kg)", + "name-metric-ton": "metric ton (t)", + "name-milligram": "milligram (mg)", + "name-pound": "pound (lb)" + }, + "name": "Mass" + }, + "misc": { + "formats": { + "name-candala": "Candela (cd)", + "name-decibel": "Decibel", + "name-hexadecimal": "Hexadecimal", + "name-hexadecimal-0x": "Hexadecimal (0x)", + "name-humidity": "Humidity (%H)", + "name-locale": "Locale format", + "name-number": "Number", + "name-percent-1": "Percent (0.0-1.0)", + "name-percent-100": "Percent (0-100)", + "name-pixels": "Pixels", + "name-scientific": "Scientific notation", + "name-short": "short", + "name-si-short": "SI short", + "name-string": "String" + }, + "name": "Misc" + }, + "pressure": { + "formats": { + "name-bars": "Bars", + "name-hectopascals": "Hectopascals", + "name-inches-mercury": "Inches of mercury", + "name-kilobars": "Kilobars", + "name-kilopascals": "Kilopascals", + "name-millibars": "Millibars", + "name-pascals": "Pascals", + "name-psi": "PSI" + }, + "name": "Pressure" + }, + "radiation": { + "formats": { + "name-becquerel": "Becquerel (Bq)", + "name-curie": "curie (Ci)", + "name-exposure": "Exposure (C/kg)", + "name-gray": "Gray (Gy)", + "name-microsievert": "microSievert (µSv)", + "name-microsievert-hour": "microSievert/hour (µSv/h)", + "name-millisievert": "milliSievert (mSv)", + "name-millisievert-hour": "milliSievert/hour (mSv/h)", + "name-rad": "rad", + "name-rem": "rem", + "name-roentgen": "roentgen (R)", + "name-sievert": "Sievert (Sv)", + "name-sievert-hour": "Sievert/hour (Sv/h)" + }, + "name": "Radiation" + }, + "rotational-speed": { + "formats": { + "name-degrees-sec": "Degrees per second (°/s)", + "name-gigahertz": "Gigahertz (GHz)", + "name-hertz": "Hertz (Hz)", + "name-kilohertz": "Kilohertz (kHz)", + "name-megahertz": "Megahertz (MHz)", + "name-radians-sec": "Radians per second (rad/s)", + "name-rpm": "Revolutions per minute (rpm)" + }, + "name": "Rotational Speed" + }, + "temperature": { + "formats": { + "name-celsius": "Celsius (°C)", + "name-fahrenheit": "Fahrenheit (°F)", + "name-kelvin": "Kelvin (K)" + }, + "name": "Temperature" + }, + "throughput": { + "formats": { + "name-counts-min": "counts/min (cpm)", + "name-counts-sec": "counts/sec (cps)", + "name-events-min": "events/min (epm)", + "name-events-sec": "events/sec (eps)", + "name-io-ops-sec": "I/O ops/sec (iops)", + "name-messages-min": "messages/min (mpm)", + "name-messages-sec": "messages/sec (mps)", + "name-ops-min": "ops/min (opm)", + "name-ops-sec": "ops/sec (ops)", + "name-reads-min": "reads/min (rpm)", + "name-reads-sec": "reads/sec (rps)", + "name-records-min": "records/min (rpm)", + "name-records-sec": "records/sec (rps)", + "name-requests-min": "requests/min (rpm)", + "name-requests-sec": "requests/sec (rps)", + "name-rows-min": "rows/min (rpm)", + "name-rows-sec": "rows/sec (rps)", + "name-writes-min": "writes/min (wpm)", + "name-writes-sec": "writes/sec (wps)" + }, + "name": "Throughput" + }, + "time": { + "formats": { + "name-clock-ms": "clock (ms)", + "name-clock-s": "clock (s)", + "name-days": "days (d)", + "name-duration-dhms": "duration (d hh:mm:ss)", + "name-duration-hms": "duration (hh:mm:ss)", + "name-duration-ms": "duration (ms)", + "name-duration-s": "duration (s)", + "name-hertz": "Hertz (1/s)", + "name-hours": "hours (h)", + "name-microseconds": "microseconds (µs)", + "name-milliseconds": "milliseconds (ms)", + "name-minutes": "minutes (m)", + "name-nanoseconds": "nanoseconds (ns)", + "name-seconds": "seconds (s)", + "name-timeticks": "Timeticks (s/100)" + }, + "name": "Time" + }, + "velocity": { + "formats": { + "name-kilometers-hour": "kilometers/hour (km/h)", + "name-knot": "knot (kn)", + "name-meters-second": "meters/second (m/s)", + "name-miles-hour": "miles/hour (mph)" + }, + "name": "Velocity" + }, + "volume": { + "formats": { + "name-cubic-decimeter": "cubic decimeter", + "name-cubic-meter": "cubic meter", + "name-gallons": "gallons", + "name-litre": "litre (L)", + "name-millilitre": "millilitre (mL)", + "name-normal-cubic-meter": "Normal cubic meter" + }, + "name": "Volume" + } + } + } + }, "grafana-ui": { "action-editor": { "button": { diff --git a/public/locales/i18next-parser.config.cjs b/public/locales/i18next-parser.config.cjs index 10f3bf00594..972a9cad866 100644 --- a/public/locales/i18next-parser.config.cjs +++ b/public/locales/i18next-parser.config.cjs @@ -14,6 +14,7 @@ module.exports = { '!../../public/app/extensions/**/*', // Don't extract from Enterprise '!../../public/app/plugins/datasource/**/*', // Don't extract from datasource plugins '../../packages/grafana-ui/**/*.{tsx,ts}', + '../../packages/grafana-data/**/*.{tsx,ts}', ], output: './public/locales/$LOCALE/$NAMESPACE.json', }; diff --git a/public/test/jest-setup.ts b/public/test/jest-setup.ts index af0f1565616..d0ccb095e24 100644 --- a/public/test/jest-setup.ts +++ b/public/test/jest-setup.ts @@ -4,7 +4,15 @@ import './global-jquery-shim'; import { TransformStream } from 'node:stream/web'; import { TextEncoder, TextDecoder } from 'util'; -import { EventBusSrv } from '@grafana/data'; +// we need to isolate the `@grafana/data` module here now that it depends on `@grafana/i18n` +jest.isolateModulesAsync(async () => { + const { EventBusSrv } = await import('@grafana/data'); + const testAppEvents = new EventBusSrv(); + jest.mock('../app/core/core', () => ({ + ...jest.requireActual('../app/core/core'), + appEvents: testAppEvents, + })); +}); import { GrafanaBootConfig } from '@grafana/runtime'; import 'blob-polyfill'; @@ -14,7 +22,6 @@ import './mocks/workers'; import '../vendor/flot/jquery.flot'; import '../vendor/flot/jquery.flot.time'; -const testAppEvents = new EventBusSrv(); const global = window as any; // mock the default window.grafanaBootData settings @@ -61,11 +68,6 @@ global.TransformStream = TransformStream; // add scrollTo interface since it's not implemented in jsdom Element.prototype.scrollTo = () => {}; -jest.mock('../app/core/core', () => ({ - ...jest.requireActual('../app/core/core'), - appEvents: testAppEvents, -})); - const throwUnhandledRejections = () => { process.on('unhandledRejection', (err) => { throw err; diff --git a/yarn.lock b/yarn.lock index 60fd9a01680..84667f53164 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3099,6 +3099,7 @@ __metadata: resolution: "@grafana/data@workspace:packages/grafana-data" dependencies: "@braintree/sanitize-url": "npm:7.0.1" + "@grafana/i18n": "npm:12.1.0-pre" "@grafana/schema": "npm:12.1.0-pre" "@grafana/tsconfig": "npm:^2.0.0" "@leeoniya/ufuzzy": "npm:1.0.18"