Merge branch 'main' of https://github.com/grafana/grafana into affix-feature-branch
# Conflicts: # .betterer.results
This commit is contained in:
+166
-13
@@ -453,7 +453,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
|
||||
],
|
||||
"packages/grafana-prometheus/src/language_utils.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
@@ -2653,18 +2654,6 @@ exports[`better eslint`] = {
|
||||
"public/app/features/provisioning/GettingStarted/SidebarItem.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Job/RecentJobs.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Repository/RepositoryCard.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Repository/RepositoryOverview.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "2"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "3"]
|
||||
],
|
||||
"public/app/features/query/components/QueryEditorRow.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
@@ -2850,6 +2839,9 @@ exports[`better eslint`] = {
|
||||
"public/app/features/transformers/editors/EnumMappingRow.tsx:5381": [
|
||||
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
|
||||
],
|
||||
"public/app/features/transformers/editors/FormatStringTransformerEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/transformers/editors/GroupByTransformerEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@@ -3810,6 +3802,9 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/panel/geomap/layers/basemaps/esri.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/layers/data/routeLayer.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/layers/registry.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
@@ -4235,6 +4230,164 @@ exports[`no undocumented stories`] = {
|
||||
}`
|
||||
};
|
||||
|
||||
exports[`no skipping a11y tests in stories`] = {
|
||||
value: `{
|
||||
"packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Button/Button.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Carousel/Carousel.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Cascader/Cascader.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ColorPicker/ColorPickerInput.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/MultiCombobox.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/FormField/FormField.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/Checkbox.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/Field.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/FieldArray.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/FieldSet.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/Form.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/InlineField.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/InlineToast/InlineToast.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Input/Input.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Layout/Grid/Grid.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Layout/Stack/Stack.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Link/TextLink.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/LoadingBar/LoadingBar.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Menu/Menu.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Modal/Modal.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/PageLayout/PageToolbar.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/QueryField/QueryField.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ScrollContainer/ScrollContainer.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Segment/Segment.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Select/Select.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Select/SelectPerf.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Slider/Slider.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Switch/Switch.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Table/Table.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Tags/TagList.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Text/Text.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ThemeDemos/Typography.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/VizLayout/VizLayout.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx:5381": [
|
||||
[0, 0, 0, "No skipping of a11y tests in stories. Please fix the component or story instead.", "5381"]
|
||||
]
|
||||
}`
|
||||
};
|
||||
|
||||
exports[`no gf-form usage`] = {
|
||||
value: `{
|
||||
"packages/grafana-prometheus/src/components/PromExploreExtraField.tsx:5381": [
|
||||
|
||||
+23
-1
@@ -17,13 +17,35 @@ export default {
|
||||
countEslintErrors()
|
||||
.include('**/*.{ts,tsx}')
|
||||
.exclude(new RegExp(eslintPathsToIgnore.join('|'))),
|
||||
'no undocumented stories': () => countUndocumentedStories().include('**/!(*.internal).story.tsx'),
|
||||
'no undocumented stories': () => countUndocumentedStories().include('**/*.story.tsx'),
|
||||
'no skipping a11y tests in stories': () => countSkippedA11yTestStories().include('**/*.story.tsx'),
|
||||
'no gf-form usage': () =>
|
||||
regexp(/gf-form/gm, 'gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.')
|
||||
.include('**/*.{ts,tsx,html}')
|
||||
.exclude(new RegExp('packages/grafana-ui/src/themes/GlobalStyles')),
|
||||
};
|
||||
|
||||
function countSkippedA11yTestStories() {
|
||||
return new BettererFileTest(async (filePaths, fileTestResult) => {
|
||||
await Promise.all(
|
||||
filePaths.map(async (filePath) => {
|
||||
// look for skipped a11y tests
|
||||
const skipRegex = new RegExp("a11y: { test: 'off' }", 'gm');
|
||||
|
||||
const fileText = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
const hasSkip = skipRegex.test(fileText);
|
||||
if (hasSkip) {
|
||||
// In this case the file contents don't matter:
|
||||
const file = fileTestResult.addFile(filePath, '');
|
||||
// Add the issue to the first character of the file:
|
||||
file.addIssue(0, 0, 'No skipping of a11y tests in stories. Please fix the component or story instead.');
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function countUndocumentedStories() {
|
||||
return new BettererFileTest(async (filePaths, fileTestResult) => {
|
||||
await Promise.all(
|
||||
|
||||
+186
-9
@@ -159,7 +159,7 @@
|
||||
/pkg/services/preference/ @grafana/grafana-backend-group
|
||||
/pkg/services/provisioning/ @grafana/grafana-search-and-storage
|
||||
/pkg/services/provisioning/alerting/ @grafana/alerting-backend
|
||||
/pkg/services/query/ @grafana/grafana-app-platform-squad
|
||||
/pkg/services/query/ @grafana/grafana-datasources-core-services
|
||||
/pkg/services/queryhistory/ @grafana/observability-traces-and-profiling
|
||||
/pkg/services/quota/ @grafana/grafana-search-and-storage
|
||||
/pkg/services/screenshot/ @grafana/grafana-backend-group
|
||||
@@ -181,6 +181,9 @@
|
||||
/pkg/tests/ @grafana/grafana-backend-services-squad
|
||||
/pkg/tests/apis/ @grafana/grafana-app-platform-squad
|
||||
/pkg/tests/apis/alerting @grafana/grafana-app-platform-squad @grafana/alerting-backend
|
||||
/pkg/tests/apis/features @grafana/grafana-backend-services-squad
|
||||
/pkg/tests/apis/folder @grafana/grafana-search-and-storage
|
||||
/pkg/tests/apis/iam @grafana/identity-access-team
|
||||
/pkg/tests/api/correlations/ @grafana/datapro
|
||||
/pkg/tsdb/grafanads/ @grafana/grafana-backend-group
|
||||
/pkg/tsdb/opentsdb/ @grafana/partner-datasources
|
||||
@@ -409,11 +412,92 @@
|
||||
/e2e-playwright/test-plugins/grafana-extensionstest-app/ @grafana/plugins-platform-frontend
|
||||
|
||||
# Packages
|
||||
/packages/ @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/README.md @grafana/grafana-frontend-platform
|
||||
/packages/rollup.config.parts.ts @grafana/frontend-ops
|
||||
|
||||
# @grafana/alerting
|
||||
/packages/grafana-alerting/ @grafana/alerting-frontend
|
||||
|
||||
# @grafana/data
|
||||
/packages/grafana-data/CHANGELOG.md @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/LICENSE_APACHE2 @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/README.md @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/package.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/project.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/rollup.config.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/index.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/internal/index.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/unstable.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/tsconfig.build.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/tsconfig.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/test/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/typings/ @grafana/grafana-frontend-platform
|
||||
|
||||
/packages/grafana-data/src/**/*logs* @grafana/observability-logs
|
||||
/packages/grafana-data/src/context/plugins/ @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/dataframe/ @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/datetime/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/events/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/field/ @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/geo/ @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/monaco/ @grafana/partner-datasources
|
||||
/packages/grafana-data/src/panel/ @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/query/ @grafana/grafana-datasources-core-services
|
||||
/packages/grafana-data/src/rbac/ @grafana/access-squad
|
||||
/packages/grafana-data/src/table/ @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/text/ @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/themes/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/transformations/ @grafana/datapro
|
||||
/packages/grafana-data/src/types/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/__snapshots__/ @grafanabot
|
||||
/packages/grafana-data/src/utils/anyToNumber.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/arrayUtils* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/binaryOperators.ts @grafana/datapro
|
||||
/packages/grafana-data/src/utils/csv* @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/dataLinks* @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/utils/datasource.ts @grafana/grafana-datasources-core-services
|
||||
/packages/grafana-data/src/utils/docs.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/deprecationWarning* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/featureToggles.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/fieldParser.ts @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/flotPairs* @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/fuzzySearch* @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-data/src/utils/labels* @grafana/observability-logs
|
||||
/packages/grafana-data/src/utils/legend* @grafana/oss-big-tent
|
||||
/packages/grafana-data/src/utils/location* @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-data/src/utils/LocalStorageValueProvider.tsx @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/makeClassES5Compatible.ts @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/utils/matchPluginId* @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/utils/namedColorsPalette* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/nodeGraph.ts @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-data/src/utils/numbers.ts @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/object.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/OptionsUIBuilders.ts @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/utils/Registry* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/selectUtils.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/series* @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/store* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/testdata/ @grafana/dataviz-squad
|
||||
/packages/grafana-data/src/utils/tests/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-data/src/utils/throwIfAngular* @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/utils/unaryOperators.ts @grafana/datapro
|
||||
/packages/grafana-data/src/utils/url* @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-data/src/utils/valueMappings* @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/utils/variables.ts @grafana/plugins-platform-frontend
|
||||
/packages/grafana-data/src/utils/withLoadingIndicator.ts @grafana/access-squad @grafana/alerting-frontend
|
||||
/packages/grafana-data/src/valueFormats/ @grafana/dashboards-squad
|
||||
/packages/grafana-data/src/vector/ @grafana/dataviz-squad
|
||||
|
||||
# @grafana/e2e-selectors
|
||||
/packages/grafana-e2e-selectors/ @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/eslint-plugin
|
||||
/packages/grafana-eslint-rules/ @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/flamegraph
|
||||
/packages/grafana-flamegraph/ @grafana/observability-traces-and-profiling
|
||||
|
||||
# @grafana/o11y-ds-frontend
|
||||
/packages/grafana-o11y-ds-frontend/ @grafana/observability-logs
|
||||
/packages/grafana-o11y-ds-frontend/src/IntervalInput/ @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-o11y-ds-frontend/src/NodeGraph/ @grafana/observability-traces-and-profiling
|
||||
@@ -422,16 +506,104 @@
|
||||
/packages/grafana-o11y-ds-frontend/src/TraceToLogs/ @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-o11y-ds-frontend/src/TraceToMetrics/ @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-o11y-ds-frontend/src/TraceToProfiles/ @grafana/observability-traces-and-profiling
|
||||
|
||||
# @grafana/plugin-configs
|
||||
/packages/grafana-plugin-configs/ @grafana/plugins-platform-frontend
|
||||
|
||||
# @grafana/prometheus
|
||||
/packages/grafana-prometheus/ @grafana/oss-big-tent
|
||||
/packages/grafana-schema/src/**/*canvas* @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/*tempo* @grafana/observability-traces-and-profiling
|
||||
|
||||
# @grafana/runtime
|
||||
/packages/grafana-runtime/CHANGELOG.md @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/LICENSE_APACHE2 @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/README.md @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/package.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/project.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/rollup.config.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/index.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/src/internal/index.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/src/unstable.ts @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/tsconfig.build.json @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/tsconfig.json @grafana/grafana-frontend-platform
|
||||
|
||||
/packages/grafana-runtime/src/analytics @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/analytics/plugins @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/src/components/DataSourcePicker* @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/components/EmbeddedDashboard.tsx @grafana/dashboards-squad
|
||||
/packages/grafana-runtime/src/components/FolderPicker.tsx @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/components/PanelRenderer.tsx @grafana/dashboards-squad
|
||||
/packages/grafana-runtime/src/components/PanelDataErrorView.tsx @grafana/dashboards-squad
|
||||
/packages/grafana-runtime/src/components/PluginPage.tsx @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/components/QueryEditorWithMigration* @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
|
||||
/packages/grafana-runtime/src/config.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/services/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/services/pluginExtensions @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/src/services/CorrelationsService.ts @grafana/datapro
|
||||
/packages/grafana-runtime/src/services/LocationService.test.tsx @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/services/LocationService.tsx @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/services/LocationSrv.ts @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/services/live.ts @grafana/dashboards-squad
|
||||
/packages/grafana-runtime/src/utils/chromeHeaderHeight.ts @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/utils/DataSourceWithBackend* @grafana/grafana-datasources-core-services
|
||||
/packages/grafana-runtime/src/utils/licensing.ts @grafana/grafana-operator-experience-squad
|
||||
/packages/grafana-runtime/src/utils/logging.ts @grafana/grafana-frontend-platform
|
||||
/packages/grafana-runtime/src/utils/migrationHandler* @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
|
||||
/packages/grafana-runtime/src/utils/plugin.ts @grafana/plugins-platform-frontend
|
||||
/packages/grafana-runtime/src/utils/publicDashboardQueryHandler.ts @grafana/grafana-operator-experience-squad
|
||||
/packages/grafana-runtime/src/utils/queryResponse* @grafana/grafana-datasources-core-services
|
||||
/packages/grafana-runtime/src/utils/rbac.ts @grafana/identity-access-team
|
||||
/packages/grafana-runtime/src/utils/returnToPrevious.ts @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-runtime/src/utils/toDataQueryError.ts @grafana/grafana-datasources-core-services
|
||||
/packages/grafana-runtime/src/utils/userStorage* @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/schema
|
||||
/packages/grafana-schema/ @grafana/grafana-app-platform-squad
|
||||
|
||||
/packages/grafana-schema/src/**/annotationslist @grafana/dashboards-squad
|
||||
/packages/grafana-schema/src/**/azuremonitor @grafana/partner-datasources
|
||||
/packages/grafana-schema/src/**/barchart @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/bargauge @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/candlestick @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/canvas @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/cloudwatch @grafana/aws-datasources
|
||||
/packages/grafana-schema/src/**/dashboard @grafana/dashboards-squad
|
||||
/packages/grafana-schema/src/**/dashboardlist @grafana/grafana-search-navigate-organise
|
||||
/packages/grafana-schema/src/**/datagrid @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/debug @ryantxu
|
||||
/packages/grafana-schema/src/**/elasticsearch @grafana/partner-datasources
|
||||
/packages/grafana-schema/src/**/gauge @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/geomap @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/googlecloudmonitoring @grafana/partner-datasources
|
||||
/packages/grafana-schema/src/**/grafanapyroscope @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-schema/src/**/heatmap @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/histogram @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/librarypanel @grafana/sharing-squad
|
||||
/packages/grafana-schema/src/**/logs @grafana/observability-logs
|
||||
/packages/grafana-schema/src/**/logsnew @grafana/observability-logs
|
||||
/packages/grafana-schema/src/**/loki @grafana/oss-big-tent @grafana/observability-logs
|
||||
/packages/grafana-schema/src/**/news @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/nodegraph @grafana/observability-traces-and-profiling @grafana/app-o11y-visualizations
|
||||
/packages/grafana-schema/src/**/parca @grafana/oss-big-tent
|
||||
/packages/grafana-schema/src/**/piechart @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/publicdashboard @grafana/sharing-squad
|
||||
/packages/grafana-schema/src/**/stat @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/statetimeline @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/statushistory @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/table @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/tempo @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-schema/src/**/text @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/timeseries @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/trend @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/xychart @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/xychart2 @grafana/dataviz-squad
|
||||
|
||||
# @grafana/sql
|
||||
/packages/grafana-sql/ @grafana/partner-datasources @grafana/oss-big-tent
|
||||
/packages/grafana-ui/.storybook/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-ui/src/components/ @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/ui
|
||||
/packages/grafana-ui/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-ui/src/components/BarGauge/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/components/DataLinks/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/components/DateTimePickers/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-ui/src/components/Gauge/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/components/PluginSignatureBadge/ @grafana/plugins-platform-frontend
|
||||
/packages/grafana-ui/src/components/Sparkline/ @grafana/grafana-frontend-platform @grafana/app-o11y-visualizations
|
||||
@@ -446,9 +618,13 @@
|
||||
/packages/grafana-ui/src/graveyard/Graph/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/graveyard/GraphNG/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/graveyard/TimeSeries/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/utils/storybook/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-alerting/ @grafana/alerting-frontend
|
||||
/packages/grafana-ui/tsconfig.build.json @grafana/frontend-ops
|
||||
/packages/grafana-ui/tsconfig.json @grafana/frontend-ops
|
||||
|
||||
# @grafana/i18n
|
||||
/packages/grafana-i18n/ @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
|
||||
|
||||
# @grafana/test-utils
|
||||
/packages/grafana-test-utils @grafana/grafana-frontend-platform
|
||||
|
||||
# root files, mostly frontend
|
||||
@@ -826,6 +1002,7 @@ embed.go @grafana/grafana-as-code
|
||||
/.github/workflows/publish-technical-documentation-release.yml @grafana/docs-tooling
|
||||
/.github/workflows/scripts/json-file-to-job-output.js @grafana/plugins-platform-frontend
|
||||
/.github/workflows/stale.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/storybook-a11y.yml @grafana/grafana-frontend-platform
|
||||
/.github/workflows/storybook-verification.yml @grafana/grafana-frontend-platform
|
||||
/.github/workflows/storybook-verification-playwright.yml @grafana/grafana-frontend-platform
|
||||
/.github/workflows/update-make-docs.yml @grafana/docs-tooling
|
||||
|
||||
@@ -47,6 +47,10 @@ runs:
|
||||
- '.github/actions/checkout/**'
|
||||
- '**/go.mod'
|
||||
- '**/go.sum'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- 'go.work'
|
||||
- 'go.work.sum'
|
||||
- '**.go'
|
||||
- 'pkg/**'
|
||||
- '!pkg/**.md'
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
'react-refresh',
|
||||
|
||||
"@types/history", // this can be removed entirely when we upgrade history since v5 exposes types directly
|
||||
"cypress", // cypress use is deprecated, we should not bump it anymore
|
||||
"history", // we should bump this together with react-router-dom (see https://github.com/grafana/grafana/issues/76744)
|
||||
"react-router", // we should bump this together with history and react-router-dom
|
||||
"react-router-dom", // we should bump this together with history (see https://github.com/grafana/grafana/issues/76744)
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: marocchino/sticky-pull-request-comment@d2ad0de260ae8b0235ce059e63f2949ba9e05943 # v2.9.3
|
||||
- uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4
|
||||
with:
|
||||
message: |
|
||||
Since you've added the `Add to what's new` label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature.
|
||||
|
||||
@@ -271,7 +271,7 @@ jobs:
|
||||
# Comment on the PR
|
||||
- name: Comment on PR
|
||||
if: steps.levitate-run.outputs.exit_code == 1
|
||||
uses: marocchino/sticky-pull-request-comment@d2ad0de260ae8b0235ce059e63f2949ba9e05943
|
||||
uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405
|
||||
with:
|
||||
header: levitate-breaking-change-comment
|
||||
number: ${{ github.event.pull_request.number }}
|
||||
@@ -288,7 +288,7 @@ jobs:
|
||||
# Remove comment from the PR (no more breaking changes)
|
||||
- name: Remove comment from PR
|
||||
if: steps.levitate-run.outputs.exit_code == 0
|
||||
uses: marocchino/sticky-pull-request-comment@d2ad0de260ae8b0235ce059e63f2949ba9e05943
|
||||
uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405
|
||||
with:
|
||||
header: levitate-breaking-change-comment
|
||||
number: ${{ github.event.pull_request.number }}
|
||||
|
||||
@@ -119,12 +119,36 @@ jobs:
|
||||
SLACK_WEBHOOK_URL: ${{ env.AUTOTRIAGER_SLACK_WEBHOOK_URL }}
|
||||
auto-label-internal-issues:
|
||||
needs: [main]
|
||||
if: github.repository == 'grafana/grafana'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: "Get vault secrets"
|
||||
id: vault-secrets
|
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@main # zizmor: ignore[unpinned-uses]
|
||||
with:
|
||||
# Secrets placed in the ci/repo/grafana/grafana/plugins_platform_issue_triager path in Vault
|
||||
repo_secrets: |
|
||||
GITHUB_APP_ID=plugins_platform_issue_triager_github_bot:app_id
|
||||
GITHUB_APP_PRIVATE_KEY=plugins_platform_issue_triager_github_bot:app_pem
|
||||
- name: Generate token
|
||||
id: generate_token
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ env.GITHUB_APP_ID }}
|
||||
private-key: ${{ env.GITHUB_APP_PRIVATE_KEY }}
|
||||
permission-members: read
|
||||
- name: Check if member of grafana org
|
||||
id: check-if-grafana-org-member
|
||||
continue-on-error: true
|
||||
run: gh api https://api.github.com/orgs/grafana/members/${{ env.ACTOR }} >/dev/null 2>&1 && echo "is_grafana_org_member=true" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||
ACTOR: ${{ github.actor }}
|
||||
- name: "Auto label internal issues"
|
||||
if: github.repository == 'grafana/grafana' && (github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER')
|
||||
if: steps.check-if-grafana-org-member.outputs.is_grafana_org_member == 'true' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER'
|
||||
run: gh issue edit "$NUMBER" --add-label "$LABELS"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -286,6 +286,7 @@ jobs:
|
||||
/home/bench/tests/playwright-results.json
|
||||
|
||||
- name: Upload HTML report
|
||||
id: upload-html
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-html-${{ github.run_number }}
|
||||
@@ -304,10 +305,13 @@ jobs:
|
||||
- name: Show test results
|
||||
env:
|
||||
FAILED: ${{ steps.check-jobs.outputs.any-failed }}
|
||||
REPORT_URL: ${{ steps.upload-html.outputs.artifact-url }}
|
||||
# sed removes the leading `../../src/` from the paths
|
||||
run: |
|
||||
npx playwright merge-reports --reporter list ./all-blob-reports | sed 's|\(\.\./\)\{1,\}src/|/|g'
|
||||
npx playwright merge-reports --reporter list ./blobs | sed 's|\(\.\./\)\{1,\}src/|/|g'
|
||||
if [ "$FAILED" = "true" ]; then
|
||||
echo ""
|
||||
echo "Download the test report from $REPORT_URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -4,18 +4,31 @@ on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- .github/workflows/pr-go-workspace-check.yml
|
||||
- go.mod
|
||||
- go.sum
|
||||
- go.work
|
||||
- go.work.sum
|
||||
- '**/go.mod'
|
||||
- '**/go.sum'
|
||||
- '**.go'
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
check:
|
||||
detect-changes:
|
||||
name: Detect whether code changed
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
changed: ${{ steps.detect-changes.outputs.backend }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true # required to get more history in the changed-files action
|
||||
fetch-depth: 2
|
||||
- name: Detect changes
|
||||
id: detect-changes
|
||||
uses: ./.github/actions/change-detection
|
||||
with:
|
||||
self: .github/workflows/pr-go-workspace-check.yml
|
||||
|
||||
check-workspace:
|
||||
needs: detect-changes
|
||||
if: needs.detect-changes.outputs.changed == 'true'
|
||||
name: Go Workspace Check
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -47,6 +60,8 @@ jobs:
|
||||
run: ./scripts/go-workspace/validate-dockerfile.sh
|
||||
|
||||
check-wire:
|
||||
needs: detect-changes
|
||||
if: needs.detect-changes.outputs.changed == 'true'
|
||||
name: Check Wire Changes
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -114,3 +129,29 @@ jobs:
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# This is the job that is actually required by rulesets.
|
||||
# We want to only require one job instead of all the individual tests.
|
||||
# Future work also allows us to start skipping some tests based on changed files.
|
||||
required-go-workspace-check:
|
||||
needs:
|
||||
- check-workspace
|
||||
- check-wire
|
||||
# always() is the best function here.
|
||||
# success() || failure() will skip this function if any need is also skipped.
|
||||
# That means conditional jobs will fail the entire requirement check.
|
||||
if: always()
|
||||
|
||||
name: All Go Workspace Checks complete
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check the checks
|
||||
env:
|
||||
NEEDS: ${{ toJson(needs) }}
|
||||
run: |
|
||||
FAILURES="$(echo "$NEEDS" | jq 'with_entries(select(.value.result == "failure")) | map_values(.result)')"
|
||||
echo "$FAILURES"
|
||||
if [ "$(echo "$FAILURES" | jq '. | length')" != "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "All OK!"
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
name: Run Storybook a11y tests
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-*.*.*
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
detect-changes:
|
||||
name: Detect whether code changed
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
changed: ${{ steps.detect-changes.outputs.frontend }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true # required to get more history in the changed-files action
|
||||
fetch-depth: 2
|
||||
- name: Detect changes
|
||||
id: detect-changes
|
||||
uses: ./.github/actions/change-detection
|
||||
with:
|
||||
self: .github/workflows/storybook-a11y.yml
|
||||
|
||||
test-storybook-a11y:
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
needs: detect-changes
|
||||
if: needs.detect-changes.outputs.changed == 'true'
|
||||
name: "Run Storybook a11y tests"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
- run: yarn install --immutable --check-cache
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install --with-deps
|
||||
- name: Start Storybook
|
||||
run: yarn storybook &
|
||||
- name: Run tests
|
||||
# the chromium browser used by Playwright sets its locale to "en_US@posix" by default
|
||||
# this is not a valid language code, and causes some stories to fail to load!
|
||||
# instead, we set the LANG environment variable to en_US to override this
|
||||
# see https://github.com/microsoft/playwright/issues/34046
|
||||
env:
|
||||
LANG: en_US
|
||||
run: npx wait-on --timeout 120000 http://localhost:9001 && yarn test:storybook
|
||||
+250
@@ -1,3 +1,253 @@
|
||||
<!-- 12.1.0 START -->
|
||||
|
||||
# 12.1.0 (2025-07-23)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Access:** Disable role none option if advanced access control is not enabled [#107378](https://github.com/grafana/grafana/pull/107378), [@Jguer](https://github.com/Jguer)
|
||||
- **Alerting:** Add OAuth2 Support for Webhook Receiver [#106302](https://github.com/grafana/grafana/pull/106302), [@JacobsonMT](https://github.com/JacobsonMT)
|
||||
- **Alerting:** Add ability to import rules to GMA from Prometheus YAML [#105807](https://github.com/grafana/grafana/pull/105807), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add details to the payload when tracking import to GMA [#106404](https://github.com/grafana/grafana/pull/106404), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add export folder action to the new list view [#106256](https://github.com/grafana/grafana/pull/106256), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add filters for health and contact point in Prometheus Rules api [#106580](https://github.com/grafana/grafana/pull/106580), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Add loading spinner for loading groups state [#106289](https://github.com/grafana/grafana/pull/106289), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add need more info for import ui datasource field [#106364](https://github.com/grafana/grafana/pull/106364), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add provenance to Prometheus API [#106596](https://github.com/grafana/grafana/pull/106596), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Add provenance to remote-ruler extension response (Enterprise)
|
||||
- **Alerting:** Add simplified routing metadata to the details tab [#106403](https://github.com/grafana/grafana/pull/106403), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Add state history backend to write ALERTS metric [#104361](https://github.com/grafana/grafana/pull/104361), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Add support for Redis Sentinel for Alerting HA [#106322](https://github.com/grafana/grafana/pull/106322), [@vstpme](https://github.com/vstpme)
|
||||
- **Alerting:** Allow disabling recording rules write for a data source in the UI [#106664](https://github.com/grafana/grafana/pull/106664), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Correctly persist FiredAt in SyncRuleStatePersister [#106658](https://github.com/grafana/grafana/pull/106658), [@fayzal-g](https://github.com/fayzal-g)
|
||||
- **Alerting:** Ensure errors cleared when Alerting after error [#105246](https://github.com/grafana/grafana/pull/105246), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Evaluate all imported from Prometheus rules sequentially [#106295](https://github.com/grafana/grafana/pull/106295), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Extensible Settings module [#107831](https://github.com/grafana/grafana/pull/107831), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** Filter out rules managed by integrations and add an info alert [#106602](https://github.com/grafana/grafana/pull/106602), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Filter out synthetic datasource-managed rules when importing to GMA [#106358](https://github.com/grafana/grafana/pull/106358), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** List V2 - Add labels popup [#107193](https://github.com/grafana/grafana/pull/107193), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** List V2 - Grouped view filters [#106400](https://github.com/grafana/grafana/pull/106400), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** List V2 - Use backend filters for GMA rules [#106897](https://github.com/grafana/grafana/pull/106897), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** Make paginated rules endpoint strongly consistent (Enterprise)
|
||||
- **Alerting:** Optimize out unnecessary permission check for rule groups (Enterprise)
|
||||
- **Alerting:** Optimize prometheus api permission checks [#106299](https://github.com/grafana/grafana/pull/106299), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Optimize prometheus api permission checks (Enterprise)
|
||||
- **Alerting:** Persist alert instance FiredAt field [#105927](https://github.com/grafana/grafana/pull/105927), [@fayzal-g](https://github.com/fayzal-g)
|
||||
- **Alerting:** Remove ruler from alert list view2 [#106778](https://github.com/grafana/grafana/pull/106778), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Resend alerts for states that are missing in the eval results [#105965](https://github.com/grafana/grafana/pull/105965), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Send notifications immediately on Error|NoData -> Normal transitions [#106421](https://github.com/grafana/grafana/pull/106421), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Support PDC in Grafana-managed recording rules [#106677](https://github.com/grafana/grafana/pull/106677), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Use default_datasource_uid as the default target for recording rules in UI [#106415](https://github.com/grafana/grafana/pull/106415), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Annotations:** Use dashboard uids instead of dashboard ids [#106676](https://github.com/grafana/grafana/pull/106676), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **App Platform Provisioning:** Add experimental nanogit mode for Git Sync [#106763](https://github.com/grafana/grafana/pull/106763), [@MissingRoberto](https://github.com/MissingRoberto)
|
||||
- **Auth:** Add Azure/Entra workload identity support [#104807](https://github.com/grafana/grafana/pull/104807), [@mehighlow](https://github.com/mehighlow)
|
||||
- **Auth:** Enable improved session handling by default for OAuth and SAML [#107442](https://github.com/grafana/grafana/pull/107442), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Auth:** Enable ssoSettingsLDAP by default [#106310](https://github.com/grafana/grafana/pull/106310), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Auth:** Remove api key endpoints [#106019](https://github.com/grafana/grafana/pull/106019), [@dmihai](https://github.com/dmihai)
|
||||
- **Auth:** Remove code for authenticating API keys [#105998](https://github.com/grafana/grafana/pull/105998), [@dmihai](https://github.com/dmihai)
|
||||
- **Azure:** Support scope selection in Resource Graph queries [#105835](https://github.com/grafana/grafana/pull/105835), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Betterer:** Only allow singleton Storage use [#105310](https://github.com/grafana/grafana/pull/105310), [@tskarhed](https://github.com/tskarhed)
|
||||
- **Caching:** Remove memcached reconnect_interval setting (Enterprise)
|
||||
- **Chore:** Update k8s.io to v0.33.1 [#105307](https://github.com/grafana/grafana/pull/105307), [@ryantxu](https://github.com/ryantxu)
|
||||
- **Cloud Monitoring:** Add support for service account impersonation [#107022](https://github.com/grafana/grafana/pull/107022), [@zoltanbedi](https://github.com/zoltanbedi)
|
||||
- **CloudMigrations:** Add Mute Timings as dependency for Notification Policies [#106751](https://github.com/grafana/grafana/pull/106751), [@macabu](https://github.com/macabu)
|
||||
- **CloudWatch:** Backport aws-sdk-go-v2 update from external plugin [#107136](https://github.com/grafana/grafana/pull/107136), [@njvrzm](https://github.com/njvrzm)
|
||||
- **CloudWatch:** Improve instance attribute variable query editor [#105206](https://github.com/grafana/grafana/pull/105206), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Cloudwatch:** Add missing AWS regions [#106304](https://github.com/grafana/grafana/pull/106304), [@chriscerie](https://github.com/chriscerie)
|
||||
- **Dashboard Provisioning:** Reduce db load [#106114](https://github.com/grafana/grafana/pull/106114), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Dashboard:** Add Alert icon in library panels [#107723](https://github.com/grafana/grafana/pull/107723), [@axelavargas](https://github.com/axelavargas)
|
||||
- **Dashboard:** Add server-configurable quick ranges for the time picker [#102254](https://github.com/grafana/grafana/pull/102254), [@chodges15](https://github.com/chodges15)
|
||||
- **Dashboard:** Formatting Currency - add new custom 'financial' currency format without abbreviations [#106604](https://github.com/grafana/grafana/pull/106604), [@axelavargas](https://github.com/axelavargas)
|
||||
- **Dashboard:** Library Panels - Add ability to search by folder name [#106997](https://github.com/grafana/grafana/pull/106997), [@axelavargas](https://github.com/axelavargas)
|
||||
- **Dashboard:** Schema V2 - Auto-transform V2 dashboards in V1Resource export mode [#105997](https://github.com/grafana/grafana/pull/105997), [@axelavargas](https://github.com/axelavargas)
|
||||
- **Datasources:** Migrate to new sigv4 middleware (Enterprise)
|
||||
- **Datasources:** Update grafana-aws-sdk for new sigv4 middleware and aws-sdk-go v1 removal [#107522](https://github.com/grafana/grafana/pull/107522), [@njvrzm](https://github.com/njvrzm)
|
||||
- **DatePicker:** Add cursor not-allowed style and hover background color [#106451](https://github.com/grafana/grafana/pull/106451), [@ywzheng1](https://github.com/ywzheng1)
|
||||
- **Dependencies:** Bump Go to v1.24.4 [#106533](https://github.com/grafana/grafana/pull/106533), [@macabu](https://github.com/macabu)
|
||||
- **Dependencies:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 [#107379](https://github.com/grafana/grafana/pull/107379), [@macabu](https://github.com/macabu)
|
||||
- **Dependencies:** Bump github.com/openfga/openfga to v1.8.13 to address CVE-2025-48371 [#106064](https://github.com/grafana/grafana/pull/106064), [@macabu](https://github.com/macabu)
|
||||
- **ElasticSearch:** Remove frontend response parsing [#104148](https://github.com/grafana/grafana/pull/104148), [@nojaf](https://github.com/nojaf)
|
||||
- **Geomap:** Add HiDPI support to CARTO basemap (#81195) [#106211](https://github.com/grafana/grafana/pull/106211), [@cledwynl](https://github.com/cledwynl)
|
||||
- **Git Sync UI:** Delete Provisioned Dashboard Flow [#106593](https://github.com/grafana/grafana/pull/106593), [@ywzheng1](https://github.com/ywzheng1)
|
||||
- **Grafana/data:** Extract fuzzy search core [#107110](https://github.com/grafana/grafana/pull/107110), [@Clarity-89](https://github.com/Clarity-89)
|
||||
- **I18n:** Update eslint rule to catch some untranslated object properties [#105072](https://github.com/grafana/grafana/pull/105072), [@tomratcliffe](https://github.com/tomratcliffe)
|
||||
- **InfluxDB:** Add an optional time range filter for tag queries in the query panel autocompleteInflux tag filter [#107195](https://github.com/grafana/grafana/pull/107195), [@NikolayTsvetkov](https://github.com/NikolayTsvetkov)
|
||||
- **LBAC for data sources:** Adds team filtering for lbac rules (Enterprise)
|
||||
- **Library Panels:** Mark library panel RBAC as GA & enable by default [#106833](https://github.com/grafana/grafana/pull/106833), [@kaydelaney](https://github.com/kaydelaney)
|
||||
- **Library Panels:** Modify connection api endpoint to be compatible with unified storage [#107088](https://github.com/grafana/grafana/pull/107088), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Library elements:** Remove ability to set as "library variable" [#106594](https://github.com/grafana/grafana/pull/106594), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Library panels:** Remove `libraryPanelRBAC` feature flag, and enable rbac by default [#107222](https://github.com/grafana/grafana/pull/107222), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Loki:** Remove experimental lokiQuerySplittingConfig [#107298](https://github.com/grafana/grafana/pull/107298), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
- **Loki:** Remove experimental predefined operations [#107289](https://github.com/grafana/grafana/pull/107289), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
- **OAuth:** Add access token as third source for user info extraction [#107636](https://github.com/grafana/grafana/pull/107636), [@Jguer](https://github.com/Jguer)
|
||||
- **Plugin Extensions:** Expose PluginMeta generic in usePluginContext [#107577](https://github.com/grafana/grafana/pull/107577), [@MattIPv4](https://github.com/MattIPv4)
|
||||
- **Postgres:** Switch the datasource plugin from lib/pq to pgx [#103961](https://github.com/grafana/grafana/pull/103961), [@zoltanbedi](https://github.com/zoltanbedi)
|
||||
- **Preferences:** Use dashboard uid for the home dashboard [#106666](https://github.com/grafana/grafana/pull/106666), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Profiles:** Stop passing response headers for Grafana-Pyroscope and parca datasources [#106577](https://github.com/grafana/grafana/pull/106577), [@simonswine](https://github.com/simonswine)
|
||||
- **Prometheus:** Deprecation message for Azure auth [#106490](https://github.com/grafana/grafana/pull/106490), [@bossinc](https://github.com/bossinc)
|
||||
- **Prometheus:** Facilitate tree shaking with exports and bundler mode [#105575](https://github.com/grafana/grafana/pull/105575), [@NWRichmond](https://github.com/NWRichmond)
|
||||
- **Prometheus:** Migrate remaining selectors to data-testid [#106564](https://github.com/grafana/grafana/pull/106564), [@idastambuk](https://github.com/idastambuk)
|
||||
- **ProvisionedFolder:** Delete folder drawer [#107089](https://github.com/grafana/grafana/pull/107089), [@ywzheng1](https://github.com/ywzheng1)
|
||||
- **Provisioning:** Add pure git repository type [#106815](https://github.com/grafana/grafana/pull/106815), [@MissingRoberto](https://github.com/MissingRoberto)
|
||||
- **Querying:** Pass dashboard and panel title as headers [#107032](https://github.com/grafana/grafana/pull/107032), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
- **Remote Alertmanager:** Send SMTP config [#106337](https://github.com/grafana/grafana/pull/106337), [@santihernandezc](https://github.com/santihernandezc)
|
||||
- **Restore dashboards:** Add filters and search [#106994](https://github.com/grafana/grafana/pull/106994), [@Clarity-89](https://github.com/Clarity-89)
|
||||
- **SCIM:** Ignore unsupported fields in user PATCH requests (Enterprise)
|
||||
- **SCIM:** Implement operation for adding an externalId value to a team (Enterprise)
|
||||
- **SCIM:** Implement the add members operation in group PATCH requests (Enterprise)
|
||||
- **SCIM:** Implement the remove members operation in group PATCH requests (Enterprise)
|
||||
- **SCIM:** Update externalId field in group PATCH request (Enterprise)
|
||||
- **SQL Expressions:** Always convert on type first [#106083](https://github.com/grafana/grafana/pull/106083), [@kylebrandt](https://github.com/kylebrandt)
|
||||
- **Select:** Set min width for the current selected item when width=auto [#106131](https://github.com/grafana/grafana/pull/106131), [@tskarhed](https://github.com/tskarhed)
|
||||
- **StateTimeline:** Display false and empty string values [#107059](https://github.com/grafana/grafana/pull/107059), [@jesdavpet](https://github.com/jesdavpet)
|
||||
- **StateTimeline:** Support `NaN` and `null` value mappings [#105638](https://github.com/grafana/grafana/pull/105638), [@fastfrwrd](https://github.com/fastfrwrd)
|
||||
- **Storage:** Take `migration_locking` setting into account [#105938](https://github.com/grafana/grafana/pull/105938), [@JohnnyQQQQ](https://github.com/JohnnyQQQQ)
|
||||
- **TableNG:** Refactor to better take advantage of react-data-grid [#103755](https://github.com/grafana/grafana/pull/103755), [@leeoniya](https://github.com/leeoniya)
|
||||
- **Tables:** Pills for Table Cells [#107485](https://github.com/grafana/grafana/pull/107485), [@timlevett](https://github.com/timlevett)
|
||||
- **Teams:** Add support for updating externalId field [#106406](https://github.com/grafana/grafana/pull/106406), [@dmihai](https://github.com/dmihai)
|
||||
- **Tempo:** Enable native histograms for Tempo service graph [#105989](https://github.com/grafana/grafana/pull/105989), [@bohandley](https://github.com/bohandley)
|
||||
- **TimeRangePicker:** Highlight range on hover [#106616](https://github.com/grafana/grafana/pull/106616), [@joshhunt](https://github.com/joshhunt)
|
||||
- **TraceView:** Resource attributes links extension point [#104680](https://github.com/grafana/grafana/pull/104680), [@edvard-falkskar](https://github.com/edvard-falkskar)
|
||||
- **Transformations:** Add "Auto" mode to Organize Fields [#103055](https://github.com/grafana/grafana/pull/103055), [@gelicia](https://github.com/gelicia)
|
||||
- **Transformations:** GA the Regression transformation [#106074](https://github.com/grafana/grafana/pull/106074), [@gelicia](https://github.com/gelicia)
|
||||
- **Unified storage:** Respect GF_DATABASE_URL override [#105331](https://github.com/grafana/grafana/pull/105331), [@pstibrany](https://github.com/pstibrany)
|
||||
- **VQB:** Add selected columns to GROUP BY dropdown (#106349) [#106391](https://github.com/grafana/grafana/pull/106391), [@Shubham19032004](https://github.com/Shubham19032004)
|
||||
- **VQB:** Allow custom table names in TableSelector [#106420](https://github.com/grafana/grafana/pull/106420), [@Victorthedev](https://github.com/Victorthedev)
|
||||
- **XYChart:** Add support for x=time [#106459](https://github.com/grafana/grafana/pull/106459), [@leeoniya](https://github.com/leeoniya)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Alerting:** Fix $value type when single data source is queried [#106080](https://github.com/grafana/grafana/pull/106080), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Fix ImportToGMARules flaky test [#106495](https://github.com/grafana/grafana/pull/106495), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix RefIds not being shown when creating or editing Grafana-managed recording rule [#106840](https://github.com/grafana/grafana/pull/106840), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix contact points tab visibility when user can only create [#106735](https://github.com/grafana/grafana/pull/106735), [@JacobsonMT](https://github.com/JacobsonMT)
|
||||
- **Alerting:** Fix eval time unit in list view [#106488](https://github.com/grafana/grafana/pull/106488), [@ebuildy](https://github.com/ebuildy)
|
||||
- **Alerting:** Fix group interval override when adding new rules [#107324](https://github.com/grafana/grafana/pull/107324), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** Fix group-level labels and query_offset in the import API [#106379](https://github.com/grafana/grafana/pull/106379), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Fix notification policy conflicts originating from provenance mismatch [#107343](https://github.com/grafana/grafana/pull/107343), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Fix resolved notifications for same-label Error to Normal transitions [#106210](https://github.com/grafana/grafana/pull/106210), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Hide labels section if we only have private labels [#105996](https://github.com/grafana/grafana/pull/105996), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Annotations:** Remove prometheus from legacy runner [#106737](https://github.com/grafana/grafana/pull/106737), [@scottlepp](https://github.com/scottlepp)
|
||||
- **Azure:** Fix Application Insights metadata requests [#105614](https://github.com/grafana/grafana/pull/105614), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix duplicated trace links [#105698](https://github.com/grafana/grafana/pull/105698), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix legend formatting [#106504](https://github.com/grafana/grafana/pull/106504), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix resource name determination in template variable queries [#105705](https://github.com/grafana/grafana/pull/105705), [@aangelisc](https://github.com/aangelisc)
|
||||
- **BarChart/StateTimeline:** Use noValue setting for error message when data is empty [#107147](https://github.com/grafana/grafana/pull/107147), [@fastfrwrd](https://github.com/fastfrwrd)
|
||||
- **CloudWatch:** Fix http client handling + assume role bug [#107893](https://github.com/grafana/grafana/pull/107893), [@njvrzm](https://github.com/njvrzm)
|
||||
- **CloudWatch:** Fix proxy transport issue [#107807](https://github.com/grafana/grafana/pull/107807), [@njvrzm](https://github.com/njvrzm)
|
||||
- **Dashboard:** FF `dashboardNewLayouts` Fix library panels non-editable when multiple added [#107052](https://github.com/grafana/grafana/pull/107052), [@axelavargas](https://github.com/axelavargas)
|
||||
- **Dashboard:** Fix cache validation to prevent stale cache [#105918](https://github.com/grafana/grafana/pull/105918), [@yashschandra](https://github.com/yashschandra)
|
||||
- **Dashboard:** Fixes issue with dashboard links that include all variables [#106356](https://github.com/grafana/grafana/pull/106356), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Fix history list for dashboard uids that end in `-` [#107073](https://github.com/grafana/grafana/pull/107073), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Drilldown:** Fix js crash when using http [#105646](https://github.com/grafana/grafana/pull/105646), [@chu121su12](https://github.com/chu121su12)
|
||||
- **Fix:** Increase login_attempt.ip_address column length for IPv6 support [#107035](https://github.com/grafana/grafana/pull/107035), [@Jguer](https://github.com/Jguer)
|
||||
- **FlameGraph:** Fix bug for function names that conflict with JavaScript object prototype properties [#106338](https://github.com/grafana/grafana/pull/106338), [@simonswine](https://github.com/simonswine)
|
||||
- **Folders:** Correctly resolve nested folder breadcrumbs [#106344](https://github.com/grafana/grafana/pull/106344), [@IevaVasiljeva](https://github.com/IevaVasiljeva)
|
||||
- **GrafanaUI:** Fix Combobox ignoring loading prop [#105584](https://github.com/grafana/grafana/pull/105584), [@ValeraS](https://github.com/ValeraS)
|
||||
- **Graphite:** Fix annotation queries [#106553](https://github.com/grafana/grafana/pull/106553), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Graphite:** Fix date mutation [#107414](https://github.com/grafana/grafana/pull/107414), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Graphite:** Fix nested variable interpolation for repeated rows [#106976](https://github.com/grafana/grafana/pull/106976), [@aangelisc](https://github.com/aangelisc)
|
||||
- **K8s:** Dashboards /apis: Fix library element connections [#106734](https://github.com/grafana/grafana/pull/106734), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Loki:** Fix health check message [#107170](https://github.com/grafana/grafana/pull/107170), [@wooffie](https://github.com/wooffie)
|
||||
- **Loki:** Fix issue where step parameter using a template variable was marked as invalid [#106541](https://github.com/grafana/grafana/pull/106541), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
- **Loki:** Fix label browser not sorted after selection of a label [#107394](https://github.com/grafana/grafana/pull/107394), [@paulojmdias](https://github.com/paulojmdias)
|
||||
- **Org:** Fix org deletion [#106193](https://github.com/grafana/grafana/pull/106193), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
|
||||
- **Plugins:** Fix and encode invalid gRPC header values [#107339](https://github.com/grafana/grafana/pull/107339), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
- **PostgreSQL:** Fix error on panel when toggling sqlDatasourceDatabaseSelection feature [#106965](https://github.com/grafana/grafana/pull/106965), [@HasithDeAlwis](https://github.com/HasithDeAlwis)
|
||||
- **Profiles:** Fix for passing the response headers [#106293](https://github.com/grafana/grafana/pull/106293), [@simonswine](https://github.com/simonswine)
|
||||
- **Reporting:** Stop sending reports with Never schedule on creation (Enterprise)
|
||||
- **SCIM:** Fix PUT request for deactivating a user (Enterprise)
|
||||
- **SCIM:** Fix the removal of all members in group PUT requests (Enterprise)
|
||||
- **SCIM:** Fix user patch operation (Enterprise)
|
||||
- **Security:** Add fix for CVE-2025-3580 [#105976](https://github.com/grafana/grafana/pull/105976), [@baldm0mma](https://github.com/baldm0mma)
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108333](https://github.com/grafana/grafana/pull/108333), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Settings:** Fix reencryption and rollback of encrypted values in setting table (Enterprise)
|
||||
- **Tempo:** Fix showing dangling edges in NodeGraph [#107245](https://github.com/grafana/grafana/pull/107245), [@ifrost](https://github.com/ifrost)
|
||||
- **ToolTip:** Fix flexbox bug with tooltip when `maxWidth` is set manually [#107145](https://github.com/grafana/grafana/pull/107145), [@jdmarshall](https://github.com/jdmarshall)
|
||||
- **URLParams:** Stringify true values as key=true always (fixes issues with variables with true value) [#106440](https://github.com/grafana/grafana/pull/106440), [@torkelo](https://github.com/torkelo)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- **Alerting:** Enable recording rules by default [#105603](https://github.com/grafana/grafana/pull/105603), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
|
||||
### Plugin development fixes & changes
|
||||
|
||||
- **Carousel:** Always center image [#106468](https://github.com/grafana/grafana/pull/106468), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **Drawer:** Include divider and close button when passing a custom title element [#106896](https://github.com/grafana/grafana/pull/106896), [@ashharrison90](https://github.com/ashharrison90)
|
||||
|
||||
<!-- 12.1.0 END -->
|
||||
<!-- 12.0.3 START -->
|
||||
|
||||
# 12.0.3 (2025-07-23)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108280](https://github.com/grafana/grafana/pull/108280), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
|
||||
<!-- 12.0.3 END -->
|
||||
<!-- 11.6.4 START -->
|
||||
|
||||
# 11.6.4 (2025-07-23)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Dependencies:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 [#107555](https://github.com/grafana/grafana/pull/107555), [@macabu](https://github.com/macabu)
|
||||
- **StateTimeline:** Add endTime to tooltip [#107605](https://github.com/grafana/grafana/pull/107605), [@adela-almasan](https://github.com/adela-almasan)
|
||||
- **Unified storage:** Respect GF_DATABASE_URL override [#107573](https://github.com/grafana/grafana/pull/107573), [@pstibrany](https://github.com/pstibrany)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Alerting:** Fix group interval override when adding new rules [#107496](https://github.com/grafana/grafana/pull/107496), [@konrad147](https://github.com/konrad147)
|
||||
- **Azure:** Fix legend formatting [#106934](https://github.com/grafana/grafana/pull/106934), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix resource name determination in template variable queries [#106939](https://github.com/grafana/grafana/pull/106939), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Graphite:** Fix annotation queries [#106940](https://github.com/grafana/grafana/pull/106940), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Graphite:** Fix date mutation [#107523](https://github.com/grafana/grafana/pull/107523), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Graphite:** Fix nested variable interpolation for repeated rows [#107564](https://github.com/grafana/grafana/pull/107564), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108281](https://github.com/grafana/grafana/pull/108281), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
|
||||
<!-- 11.6.4 END -->
|
||||
<!-- 11.5.7 START -->
|
||||
|
||||
# 11.5.7 (2025-07-23)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Dependencies:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 [#107556](https://github.com/grafana/grafana/pull/107556), [@macabu](https://github.com/macabu)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure:** Fix legend formatting [#106933](https://github.com/grafana/grafana/pull/106933), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix resource name determination in template variable queries [#106938](https://github.com/grafana/grafana/pull/106938), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108280](https://github.com/grafana/grafana/pull/108280), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
|
||||
<!-- 11.5.7 END -->
|
||||
<!-- 11.4.7 START -->
|
||||
|
||||
# 11.4.7 (2025-07-23)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Dependencies:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 [#107557](https://github.com/grafana/grafana/pull/107557), [@macabu](https://github.com/macabu)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure:** Fix legend formatting [#106932](https://github.com/grafana/grafana/pull/106932), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108279](https://github.com/grafana/grafana/pull/108279), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
|
||||
<!-- 11.4.7 END -->
|
||||
<!-- 11.3.9 START -->
|
||||
|
||||
# 11.3.9 (2025-07-23)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Dependencies:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 [#107558](https://github.com/grafana/grafana/pull/107558), [@macabu](https://github.com/macabu)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure:** Fix legend formatting [#106931](https://github.com/grafana/grafana/pull/106931), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Security:** Fixes for CVE-2025-6197 and CVE-2025-6023 [#108278](https://github.com/grafana/grafana/pull/108278), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
|
||||
<!-- 11.3.9 END -->
|
||||
<!-- 12.0.2+security-01 START -->
|
||||
|
||||
# 12.0.2+security-01 (2025-07-17)
|
||||
|
||||
@@ -263,8 +263,8 @@ build-plugin-go: ## Build decoupled plugins
|
||||
build: build-go build-js ## Build backend and frontend.
|
||||
|
||||
.PHONY: run
|
||||
run: ## Build and run web server on filesystem changes. See /.bra.toml for configuration.
|
||||
$(bra) run
|
||||
run: ## Build and run backend, and watch for changes. See .air.toml for configuration.
|
||||
$(air) -c .air.toml
|
||||
|
||||
.PHONY: run-go
|
||||
run-go: ## Build and run web server immediately.
|
||||
@@ -275,9 +275,9 @@ run-go: ## Build and run web server immediately.
|
||||
run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild
|
||||
yarn start
|
||||
|
||||
.PHONY: run-air
|
||||
run-air: ## Build and run backend, and watch for changes. See .air.toml for configuration.
|
||||
$(air) -c .air.toml
|
||||
.PHONY: run-bra
|
||||
run-air: ## [Deprecated] Build and run web server on filesystem changes. See /.bra.toml for configuration.
|
||||
$(bra) run
|
||||
|
||||
.PHONY: frontend-service-check
|
||||
frontend-service-check:
|
||||
|
||||
@@ -102,6 +102,12 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
} else {
|
||||
lastCreated = time.Now()
|
||||
}
|
||||
} else {
|
||||
// Run an initial cleanup to remove old checks
|
||||
err = r.cleanupChecks(ctxWithoutCancel, logger)
|
||||
if err != nil {
|
||||
logger.Error("Error cleaning up old check reports", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,17 +138,35 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) listChecks(ctx context.Context, logger logging.Logger) ([]resource.Object, error) {
|
||||
list, err := r.client.List(ctx, r.namespace, resource.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checks := list.GetItems()
|
||||
for list.GetContinue() != "" {
|
||||
logger.Debug("List has continue token, listing next page", "continue", list.GetContinue())
|
||||
list, err = r.client.List(ctx, r.namespace, resource.ListOptions{Continue: list.GetContinue()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
checks = append(checks, list.GetItems()...)
|
||||
}
|
||||
return checks, nil
|
||||
}
|
||||
|
||||
// checkLastCreated returns the creation time of the last check created
|
||||
// regardless of its ID. This assumes that the checks are created in batches
|
||||
// so a batch will have a similar creation time.
|
||||
// In case it finds an unprocessed check from a previous run, it will set it to error.
|
||||
func (r *Runner) checkLastCreated(ctx context.Context, log logging.Logger) (time.Time, error) {
|
||||
list, err := r.client.List(ctx, r.namespace, resource.ListOptions{})
|
||||
checkList, err := r.listChecks(ctx, log)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
lastCreated := time.Time{}
|
||||
for _, item := range list.GetItems() {
|
||||
for _, item := range checkList {
|
||||
itemCreated := item.GetCreationTimestamp().Time
|
||||
if itemCreated.After(lastCreated) {
|
||||
lastCreated = itemCreated
|
||||
@@ -209,14 +233,16 @@ func (r *Runner) createChecks(ctx context.Context, logger logging.Logger) error
|
||||
|
||||
// cleanupChecks deletes the olders checks if the number of checks exceeds the limit.
|
||||
func (r *Runner) cleanupChecks(ctx context.Context, logger logging.Logger) error {
|
||||
list, err := r.client.List(ctx, r.namespace, resource.ListOptions{Limit: -1})
|
||||
checkList, err := r.listChecks(ctx, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debug("Cleaning up checks", "numChecks", len(checkList))
|
||||
|
||||
// organize checks by type
|
||||
checksByType := map[string][]resource.Object{}
|
||||
for _, check := range list.GetItems() {
|
||||
for _, check := range checkList {
|
||||
labels := check.GetLabels()
|
||||
checkType, ok := labels[checks.TypeLabel]
|
||||
if !ok {
|
||||
@@ -226,8 +252,10 @@ func (r *Runner) cleanupChecks(ctx context.Context, logger logging.Logger) error
|
||||
checksByType[checkType] = append(checksByType[checkType], check)
|
||||
}
|
||||
|
||||
for _, checks := range checksByType {
|
||||
for checkType, checks := range checksByType {
|
||||
logger.Debug("Checking checks", "checkType", checkType, "numChecks", len(checks))
|
||||
if len(checks) > r.maxHistory {
|
||||
logger.Debug("Deleting old checks", "checkType", checkType, "maxHistory", r.maxHistory, "numChecks", len(checks))
|
||||
// Sort checks by creation time
|
||||
sort.Slice(checks, func(i, j int) bool {
|
||||
ti := checks[i].GetCreationTimestamp().Time
|
||||
@@ -242,6 +270,7 @@ func (r *Runner) cleanupChecks(ctx context.Context, logger logging.Logger) error
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting check: %w", err)
|
||||
}
|
||||
logger.Debug("Deleted check", "check", check.GetStaticMetadata().Identifier())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,69 @@ func TestRunner_checkLastCreated_UnprocessedCheck(t *testing.T) {
|
||||
assert.Equal(t, expectedAnnotations, patchOperation.Value)
|
||||
}
|
||||
|
||||
func TestRunner_checkLastCreated_PaginatedResponse(t *testing.T) {
|
||||
// Create checks with different creation times
|
||||
past := time.Now().Add(-1 * time.Hour)
|
||||
now := time.Now()
|
||||
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
if options.Continue == "" {
|
||||
// First page - return oldest and middle checks with continue token
|
||||
return &advisorv0alpha1.CheckList{
|
||||
ListMeta: metav1.ListMeta{
|
||||
Continue: "continue-token-123",
|
||||
},
|
||||
Items: []advisorv0alpha1.Check{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "check-1",
|
||||
CreationTimestamp: metav1.NewTime(past),
|
||||
Annotations: map[string]string{
|
||||
checks.StatusAnnotation: "completed",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "check-2",
|
||||
CreationTimestamp: metav1.NewTime(past),
|
||||
Annotations: map[string]string{
|
||||
checks.StatusAnnotation: "completed",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// Second page - verify continue token is passed and return newest check
|
||||
assert.Equal(t, "continue-token-123", options.Continue)
|
||||
return &advisorv0alpha1.CheckList{
|
||||
Items: []advisorv0alpha1.Check{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "check-3",
|
||||
CreationTimestamp: metav1.NewTime(now),
|
||||
Annotations: map[string]string{
|
||||
checks.StatusAnnotation: "completed",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
log: &logging.NoOpLogger{},
|
||||
}
|
||||
|
||||
lastCreated, err := runner.checkLastCreated(context.Background(), &logging.NoOpLogger{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, now.Truncate(time.Second), lastCreated.Truncate(time.Second))
|
||||
}
|
||||
|
||||
func TestRunner_createChecks_ErrorOnCreate(t *testing.T) {
|
||||
mockCheckService := &MockCheckService{checks: []checks.Check{&mockCheck{id: "check-1"}}}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
)
|
||||
|
||||
func getCheck(obj resource.Object, checkMap map[string]checks.Check) (checks.Check, error) {
|
||||
@@ -198,7 +199,10 @@ func runStepsInParallel(ctx context.Context, log logging.Logger, spec *advisorv0
|
||||
}
|
||||
}()
|
||||
logger := log.With("step", step.ID())
|
||||
stepErr, err = step.Run(ctx, logger, spec, item)
|
||||
// Create a copy of the context with a cloned HTTP request to prevent
|
||||
// concurrent modifications to the same header map
|
||||
safeCtx := contexthandler.CopyWithReqContext(ctx)
|
||||
stepErr, err = step.Run(safeCtx, logger, spec, item)
|
||||
}()
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
@@ -11,7 +12,13 @@ import (
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetCheck(t *testing.T) {
|
||||
@@ -289,6 +296,67 @@ func TestProcessCheckRetry_Success(t *testing.T) {
|
||||
assert.Empty(t, obj.Status.Report.Failures)
|
||||
}
|
||||
|
||||
func TestRunStepsInParallel_ConcurrentHeaderAccess(t *testing.T) {
|
||||
// Create an HTTP request with headers to simulate the real scenario
|
||||
req, err := http.NewRequest("GET", "/test", nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("X-Test-Header", "test-value")
|
||||
req.Header.Set("X-Panel-Id", "123")
|
||||
req.Header.Set("Cookie", "session=abc123; user_pref=dark")
|
||||
|
||||
// Create a context with ReqContext that includes the HTTP request
|
||||
webCtx := &web.Context{
|
||||
Req: req,
|
||||
}
|
||||
reqCtx := &contextmodel.ReqContext{
|
||||
Context: webCtx,
|
||||
SignedInUser: &user.SignedInUser{},
|
||||
}
|
||||
|
||||
ctx := ctxkey.Set(context.Background(), reqCtx)
|
||||
|
||||
// Create steps that modify headers concurrently (simulating CookiesMiddleware behavior)
|
||||
steps := []checks.Step{
|
||||
&headerModifyingStep{headerName: "X-Test-Header", headerValue: "modified-1"},
|
||||
&headerModifyingStep{headerName: "Cookie", headerValue: "session=xyz456"},
|
||||
&headerModifyingStep{headerName: "X-Panel-Id", headerValue: "456"},
|
||||
}
|
||||
|
||||
// Create multiple items to process
|
||||
const numItems = 20
|
||||
items := make([]any, numItems)
|
||||
for i := 0; i < numItems; i++ {
|
||||
items[i] = fmt.Sprintf("item-%d", i)
|
||||
}
|
||||
|
||||
// Track panics that might occur during execution
|
||||
var panicCount int32
|
||||
originalPanicHandler := func() {
|
||||
if r := recover(); r != nil {
|
||||
panicCount++
|
||||
t.Errorf("Unexpected panic during concurrent header access: %v", r)
|
||||
}
|
||||
}
|
||||
|
||||
// This test should not panic with our fix
|
||||
t.Run("should not panic with concurrent header modifications", func(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
originalPanicHandler()
|
||||
}
|
||||
}()
|
||||
|
||||
failures, err := runStepsInParallel(ctx, logging.DefaultLogger, nil, steps, items)
|
||||
|
||||
// Verify no error occurred
|
||||
assert.NoError(t, err)
|
||||
// Should have no failures since our mock step doesn't report failures
|
||||
assert.Empty(t, failures)
|
||||
// Verify no panics occurred
|
||||
assert.Equal(t, int32(0), panicCount)
|
||||
})
|
||||
}
|
||||
|
||||
type mockClient struct {
|
||||
resource.Client
|
||||
values []any
|
||||
@@ -377,3 +445,49 @@ func (m *mockStep) Resolution() string {
|
||||
func (m *mockStep) ID() string {
|
||||
return "mock"
|
||||
}
|
||||
|
||||
// headerModifyingStep is a mock step that modifies HTTP headers to simulate
|
||||
// the behavior of CookiesMiddleware and other middleware that caused the original panic
|
||||
type headerModifyingStep struct {
|
||||
headerName string
|
||||
headerValue string
|
||||
}
|
||||
|
||||
func (h *headerModifyingStep) Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, item any) ([]advisorv0alpha1.CheckReportFailure, error) {
|
||||
// Get the request context and modify headers (this used to cause panics)
|
||||
reqCtx := contexthandler.FromContext(ctx)
|
||||
if reqCtx != nil && reqCtx.Req != nil {
|
||||
// This is the type of header modification that was causing the concurrent map access panic
|
||||
reqCtx.Req.Header.Set(h.headerName, h.headerValue)
|
||||
reqCtx.Req.Header.Add("X-Processed-By", h.ID())
|
||||
|
||||
// Also test header deletion like ClearCookieHeader does
|
||||
if h.headerName == "Cookie" {
|
||||
reqCtx.Req.Header.Del("Cookie")
|
||||
reqCtx.Req.Header.Set("Cookie", h.headerValue)
|
||||
}
|
||||
|
||||
// Test reading headers as well
|
||||
_ = reqCtx.Req.Header.Get("X-Test-Header")
|
||||
_ = reqCtx.Req.Header.Get("X-Panel-Id")
|
||||
}
|
||||
|
||||
// No failures to report
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (h *headerModifyingStep) Title() string {
|
||||
return "Header Modifying Step"
|
||||
}
|
||||
|
||||
func (h *headerModifyingStep) Description() string {
|
||||
return "A mock step that modifies HTTP headers to test concurrent access"
|
||||
}
|
||||
|
||||
func (h *headerModifyingStep) Resolution() string {
|
||||
return "This is a test step"
|
||||
}
|
||||
|
||||
func (h *headerModifyingStep) ID() string {
|
||||
return fmt.Sprintf("header-modifier-%s", h.headerName)
|
||||
}
|
||||
|
||||
+1
-2
@@ -8,5 +8,4 @@ generate: install-app-sdk update-app-sdk ## Run Grafana App SDK code generation
|
||||
--grouping=group \
|
||||
--defencoding=none \
|
||||
--noschemasinmanifest \
|
||||
--postprocess \
|
||||
--useoldmanifestkinds
|
||||
--postprocess \
|
||||
+19
-13
@@ -1,18 +1,24 @@
|
||||
package kinds
|
||||
|
||||
manifest: {
|
||||
appName: "iam"
|
||||
appName: "iam"
|
||||
groupOverride: "iam.grafana.app"
|
||||
kinds: [
|
||||
globalrole,
|
||||
globalrolebinding,
|
||||
corerole,
|
||||
role,
|
||||
rolebinding,
|
||||
resourcepermission,
|
||||
user,
|
||||
team,
|
||||
teambinding,
|
||||
serviceaccount,
|
||||
]
|
||||
versions: {
|
||||
"v0alpha1": v0alpha1
|
||||
}
|
||||
}
|
||||
|
||||
v0alpha1: {
|
||||
kinds: [
|
||||
globalrolev0alpha1,
|
||||
globalrolebindingv0alpha1,
|
||||
corerolev0alpha1,
|
||||
rolev0alpha1,
|
||||
rolebindingv0alpha1,
|
||||
resourcepermissionv0alpha1,
|
||||
userv0alpha1,
|
||||
teamv0alpha1,
|
||||
teambindingv0alpha1,
|
||||
serviceaccountv0alpha1,
|
||||
]
|
||||
}
|
||||
@@ -4,20 +4,17 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
resourcepermission: {
|
||||
resourcepermissionKind: {
|
||||
kind: "ResourcePermission"
|
||||
pluralName: "ResourcePermissions"
|
||||
current: "v0alpha1"
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.ResourcePermission
|
||||
}
|
||||
}
|
||||
resourcepermissionv0alpha1: resourcepermissionKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.ResourcePermission
|
||||
}
|
||||
}
|
||||
|
||||
+29
-38
@@ -4,56 +4,47 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
role: {
|
||||
roleKind: {
|
||||
kind: "Role"
|
||||
pluralName: "Roles"
|
||||
current: "v0alpha1"
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
corerole: {
|
||||
coreroleKind: {
|
||||
kind: "CoreRole"
|
||||
pluralName: "CoreRoles"
|
||||
current: "v0alpha1"
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
globalrole: {
|
||||
globalroleKind: {
|
||||
kind: "GlobalRole"
|
||||
pluralName: "GlobalRoles"
|
||||
current: "v0alpha1"
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
rolev0alpha1: roleKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
|
||||
corerolev0alpha1: coreroleKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
|
||||
globalrolev0alpha1: globalroleKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.RoleSpec
|
||||
}
|
||||
}
|
||||
@@ -4,38 +4,32 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
rolebinding: {
|
||||
rolebindingKind: {
|
||||
kind: "RoleBinding"
|
||||
pluralName: "RoleBindings"
|
||||
current: "v0alpha1"
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.RoleBindingSpec
|
||||
}
|
||||
}
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
globalrolebinding: {
|
||||
globalrolebindingKind: {
|
||||
kind: "GlobalRoleBinding"
|
||||
pluralName: "GlobalRoleBindings"
|
||||
current: "v0alpha1"
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.GlobalRoleBindingSpec
|
||||
}
|
||||
}
|
||||
rolebindingv0alpha1: rolebindingKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.RoleBindingSpec
|
||||
}
|
||||
}
|
||||
|
||||
globalrolebindingv0alpha1: globalrolebindingKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.GlobalRoleBindingSpec
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,17 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
serviceaccount: {
|
||||
serviceaccountKind: {
|
||||
kind: "ServiceAccount"
|
||||
pluralName: "ServiceAccounts"
|
||||
current: "v0alpha1"
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.ServiceAccountSpec
|
||||
}
|
||||
}
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
serviceaccountv0alpha1: serviceaccountKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.ServiceAccountSpec
|
||||
}
|
||||
}
|
||||
+9
-11
@@ -4,20 +4,18 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
team: {
|
||||
teamKind: {
|
||||
kind: "Team"
|
||||
pluralName: "Teams"
|
||||
current: "v0alpha1"
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.TeamSpec
|
||||
}
|
||||
}
|
||||
teamv0alpha1: teamKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.TeamSpec
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,17 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
teambinding: {
|
||||
teambindingKind: {
|
||||
kind: "TeamBinding"
|
||||
pluralName: "TeamBindings"
|
||||
current: "v0alpha1"
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.TeamBindingSpec
|
||||
}
|
||||
}
|
||||
teambindingv0alpha1: teambindingKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.TeamBindingSpec
|
||||
}
|
||||
}
|
||||
|
||||
+10
-19
@@ -4,26 +4,17 @@ import (
|
||||
"github.com/grafana/grafana/apps/iam/kinds/v0alpha1"
|
||||
)
|
||||
|
||||
user: {
|
||||
userKind: {
|
||||
kind: "User"
|
||||
pluralName: "Users"
|
||||
current: "v0alpha1"
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
validation: {
|
||||
operations: [
|
||||
"CREATE",
|
||||
"UPDATE",
|
||||
]
|
||||
}
|
||||
schema: {
|
||||
spec: v0alpha1.UserSpec
|
||||
}
|
||||
}
|
||||
codegen: {
|
||||
ts: { enabled: false }
|
||||
go: { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
userv0alpha1: userKind & {
|
||||
schema: {
|
||||
spec: v0alpha1.UserSpec
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2016,6 +2016,7 @@ enable =
|
||||
|
||||
[feature_toggles.openfeature]
|
||||
# This is EXPERIMENTAL. Please, do not use this section
|
||||
enable_api = true
|
||||
provider = static
|
||||
|
||||
[feature_toggles.openfeature.context]
|
||||
|
||||
@@ -101,11 +101,12 @@ If you want to contribute to any of the plugins listed below (that are found wit
|
||||
- grafana-postgresql-datasource
|
||||
- grafana-pyroscope-datasource
|
||||
- grafana-testdata-datasource
|
||||
- jaegar
|
||||
- jaeger
|
||||
- mysql
|
||||
- parca
|
||||
- tempo
|
||||
- zipkin
|
||||
- loki
|
||||
|
||||
To build and watch all these plugins you can run the following command. Note this can be quite resource intensive as it will start separate build processes for each plugin.
|
||||
|
||||
@@ -119,6 +120,16 @@ If, instead, you would like to build and watch a specific plugin you can run the
|
||||
yarn workspace <name_of_plugin> dev
|
||||
```
|
||||
|
||||
If you want to run multiple specific plugins, you can use the following command.
|
||||
|
||||
```
|
||||
yarn nx run-many -t dev --projects="@grafana-plugins/grafana-azure-monitor-datasource,@grafana-plugins/jaeger"
|
||||
```
|
||||
|
||||
If you're unsure of the name of the plugins you'd like to run you can query nx with the following command to get a list of all plugins:
|
||||
|
||||
`yarn nx show projects --projects="@grafana-plugins/*"`
|
||||
|
||||
Next, we'll explain how to build and run the web server that serves these frontend assets.
|
||||
|
||||
### Backend
|
||||
|
||||
@@ -79,10 +79,6 @@
|
||||
{
|
||||
"id": "max",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 300
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -280,13 +276,75 @@
|
||||
"type": "auto",
|
||||
"wrapText": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 300
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Pills"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.cellOptions",
|
||||
"value": {
|
||||
"type": "pill"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 120
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Data Link"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.cellOptions",
|
||||
"value": {
|
||||
"type": "data-links"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "links",
|
||||
"value": [
|
||||
{
|
||||
"targetBlank": true,
|
||||
"title": "Product",
|
||||
"url": "${__value.text}"
|
||||
},
|
||||
{
|
||||
"targetBlank": true,
|
||||
"title": "Grafana",
|
||||
"url": "https://grafana.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 180
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Gauge"
|
||||
},
|
||||
"properties": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 18,
|
||||
"h": 15,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
@@ -297,7 +355,10 @@
|
||||
"footer": {
|
||||
"countRows": false,
|
||||
"enablePagination": false,
|
||||
"fields": "",
|
||||
"fields": [
|
||||
"Min",
|
||||
"Max"
|
||||
],
|
||||
"reducer": [
|
||||
"max"
|
||||
],
|
||||
@@ -318,7 +379,7 @@
|
||||
"scenarioId": "random_walk_table"
|
||||
},
|
||||
{
|
||||
"csvContent": "Info,Image,Long Text\ndown,https://placecats.com/millie/300/300,\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tempus et augue et lacinia. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec eu pretium tortor. Cras venenatis sapien sed mauris gravida, ut scelerisque est fringilla. Cras lorem diam, facilisis nec malesuada in, vulputate vel enim. Etiam fringilla nisi quis felis blandit tincidunt. Cras id lacus ornare, ullamcorper nisl eget, bibendum odio. Pellentesque imperdiet, leo a imperdiet venenatis, ligula risus venenatis quam, vel euismod magna nisi sit amet leo.\"\nup,https://placecats.com/neo/300/300,\"Sed imperdiet eget diam sit amet fringilla. Curabitur quis lacus blandit, mollis diam non, accumsan tortor. Aliquam ac tellus eget dui facilisis tempor eu id nulla. Maecenas ultrices turpis eu elementum imperdiet. Fusce eget rhoncus mi, et egestas lectus. Mauris facilisis auctor enim sed malesuada. Maecenas placerat ultricies metus vitae viverra. In hac habitasse platea dictumst. Mauris ipsum nisl, dictum eu aliquam eleifend, rutrum id orci. Nullam eget dui et odio eleifend porttitor.\"\nup fast,https://placecats.com/bella/300/300,\"Proin ac libero vulputate ex vulputate pharetra ut vel lacus. Phasellus quis dolor sed leo finibus scelerisque. Ut vel finibus leo, sed viverra ipsum. Suspendisse vitae rutrum arcu. Donec sed tellus vel lectus bibendum vestibulum. Sed eu felis non velit dictum pulvinar eu et leo. Aenean et dignissim arcu. Nam luctus at neque quis efficitur. Fusce tempus at nibh a imperdiet. Nullam malesuada ac magna at facilisis. Duis pretium aliquam eros. Donec pharetra dignissim dolor non bibendum. Ut gravida mi id urna tempus, at ullamcorper felis vulputate. Duis congue augue ex, sed finibus leo ornare ut. Mauris non quam sodales, dignissim lorem eget, tincidunt mauris. Aliquam ut velit auctor, vestibulum metus sed, mollis massa.\"\ndown fast,https://placecats.com/neo_2/300/300,\"Nullam in pulvinar justo. Nunc dictum arcu ac pellentesque bibendum. Sed in erat turpis. Vestibulum eu orci ac ligula lobortis tempus. Fusce consectetur feugiat magna, eu tempor nibh vestibulum ac. Aliquam erat volutpat. Vivamus sit amet viverra enim. Quisque mollis odio nulla, nec vulputate sem placerat in. Etiam dolor sapien, pulvinar in accumsan at, consequat eget nisi. Nunc condimentum neque magna, congue consectetur dui efficitur interdum. Nam lobortis fringilla maximus. Vestibulum eu dui a velit condimentum eleifend consequat nec lectus.\"",
|
||||
"csvContent": "Info,Image,Pills,Data Link,Long Text\ndown,https://placecats.com/millie/200/400,hello,https://grafana.com,\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tempus et augue et lacinia. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec eu pretium tortor. Cras venenatis sapien sed mauris gravida, ut scelerisque est fringilla. Cras lorem diam, facilisis nec malesuada in, vulputate vel enim. Etiam fringilla nisi quis felis blandit tincidunt. Cras id lacus ornare, ullamcorper nisl eget, bibendum odio. Pellentesque imperdiet, leo a imperdiet venenatis, ligula risus venenatis quam, vel euismod magna nisi sit amet leo.\"\nup,https://placecats.com/neo/200/400,\"[1,2,3,\"\"foo\"\",\"\"bar\"\"]\",https://grafana.com/solutions/kubernetes/,\"Sed imperdiet eget diam sit amet fringilla. Curabitur quis lacus blandit, mollis diam non, accumsan tortor. Aliquam ac tellus eget dui facilisis tempor eu id nulla. Maecenas ultrices turpis eu elementum imperdiet. Fusce eget rhoncus mi, et egestas lectus. Mauris facilisis auctor enim sed malesuada. Maecenas placerat ultricies metus vitae viverra. In hac habitasse platea dictumst. Mauris ipsum nisl, dictum eu aliquam eleifend, rutrum id orci. Nullam eget dui et odio eleifend porttitor.\"\nup fast,https://placecats.com/bella/200/400,\"foo,1,4,beep\",https://k6.io/,\"Proin ac libero vulputate ex vulputate pharetra ut vel lacus. Phasellus quis dolor sed leo finibus scelerisque. Ut vel finibus leo, sed viverra ipsum. Suspendisse vitae rutrum arcu. Donec sed tellus vel lectus bibendum vestibulum. Sed eu felis non velit dictum pulvinar eu et leo. Aenean et dignissim arcu. Nam luctus at neque quis efficitur. Fusce tempus at nibh a imperdiet. Nullam malesuada ac magna at facilisis. Duis pretium aliquam eros. Donec pharetra dignissim dolor non bibendum. Ut gravida mi id urna tempus, at ullamcorper felis vulputate. Duis congue augue ex, sed finibus leo ornare ut. Mauris non quam sodales, dignissim lorem eget, tincidunt mauris. Aliquam ut velit auctor, vestibulum metus sed, mollis massa.\"\ndown fast,https://placecats.com/neo_2/200/400,\"foo,bar,baz,a longer one,bim\",https://grafana.com/products/cloud/,\"Nullam in pulvinar justo. Nunc dictum arcu ac pellentesque bibendum. Sed in erat turpis. Vestibulum eu orci ac ligula lobortis tempus. Fusce consectetur feugiat magna, eu tempor nibh vestibulum ac. Aliquam erat volutpat. Vivamus sit amet viverra enim. Quisque mollis odio nulla, nec vulputate sem placerat in. Etiam dolor sapien, pulvinar in accumsan at, consequat eget nisi. Nunc condimentum neque magna, congue consectetur dui efficitur interdum. Nam lobortis fringilla maximus. Vestibulum eu dui a velit condimentum eleifend consequat nec lectus.\"",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
@@ -344,12 +405,14 @@
|
||||
},
|
||||
"includeByName": {},
|
||||
"indexByName": {
|
||||
"A": 7,
|
||||
"A": 9,
|
||||
"Data Link": 8,
|
||||
"Image": 5,
|
||||
"Info": 1,
|
||||
"Long Text": 6,
|
||||
"Long Text": 7,
|
||||
"Max A": 3,
|
||||
"Min A": 2,
|
||||
"Pills": 6,
|
||||
"State A": 4,
|
||||
"Time A": 0
|
||||
},
|
||||
@@ -461,5 +524,5 @@
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - Table - Kitchen Sink",
|
||||
"uid": "dcb9f5e9-8066-4397-889e-864b99555dbb",
|
||||
"version": 1
|
||||
"version": 2
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ server {
|
||||
add_header 'Access-Control-Allow-Headers' '*' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
|
||||
rewrite ^/grafana-oss/11.4.0-pre/public(.*)$ $1 last;
|
||||
rewrite ^/grafana-oss/12.1.0-pre/public(.*)$ $1 last;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ labels:
|
||||
- oss
|
||||
- cloud
|
||||
- enterprise
|
||||
stage: experimental
|
||||
keywords:
|
||||
- grafana
|
||||
- grafana advisor
|
||||
@@ -17,7 +16,7 @@ keywords:
|
||||
|
||||
# Grafana Advisor
|
||||
|
||||
{{< docs/experimental product="Grafana Advisor" featureFlag="grafanaAdvisor" >}}
|
||||
{{< docs/public-preview product="Grafana Advisor" featureFlag="grafanaAdvisor" >}}
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
@@ -204,5 +204,5 @@ Now that you are familiar with Explore you can:
|
||||
- [Build dashboards](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/dashboards/build-dashboards/)
|
||||
- Create a wide variety of [visualizations](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/)
|
||||
- [Work with logs](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/explore/logs-integration/)
|
||||
- [Work with traces](https://grafana.com/docs/grafana/<GRAFANA_VERSION>)
|
||||
- [Work with traces](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/explore/trace-integration/)
|
||||
- [Create and use correlations](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/explore/correlations-editor-in-explore/)
|
||||
|
||||
@@ -150,6 +150,7 @@ The SQL conversion path:
|
||||
|
||||
- Currently, only one SQL expression is supported per panel or alert.
|
||||
- Grafana supports certain data sources. Refer to [compatible data sources](#compatible-data-sources) for a current list.
|
||||
- Autocomplete is available, but column/field autocomplete is only available after enabling the `sqlExpressionsColumnAutoComplete` feature toggle, which is provided on an experimental basis.
|
||||
|
||||
## Supported data source formats
|
||||
|
||||
|
||||
@@ -59,6 +59,11 @@ refs:
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/
|
||||
graph-styles:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/time-series/#graph-styles-options
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/time-series/#graph-styles-options
|
||||
---
|
||||
|
||||
# Table
|
||||
@@ -217,11 +222,8 @@ After you activate the table footer, make selections for the following options:
|
||||
### Cell options
|
||||
|
||||
Cell options allow you to control how data is displayed in a table.
|
||||
The options are:
|
||||
|
||||
- [Cell type](#cell-type) - Control the default cell display settings.
|
||||
- [Wrap text](#wrap-text) - Wrap text in the cell that contains the longest content in your table.
|
||||
- [Cell value inspect](#cell-value-inspect) - Enables value inspection from table cells.
|
||||
The options are differ based on the cell type that you select and are outlined within the descriptions of each cell type.
|
||||
The following table provides short descriptions for each cell type and links to a longer description and the cell type options.
|
||||
|
||||
#### Cell type
|
||||
|
||||
@@ -231,50 +233,88 @@ Additional configuration is available for some cell types.
|
||||
|
||||
If you want to apply a cell type to only some fields instead of all fields, you can do so using the **Cell options > Cell type** field override.
|
||||
|
||||
| Cell type | Description |
|
||||
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Auto | Automatically displays values with sensible defaults applied. |
|
||||
| [Sparkline](#sparkline) | Shows values rendered as a sparkline. |
|
||||
| [Colored text](#colored-text) | If thresholds are set, then the field text is displayed in the appropriate threshold color. |
|
||||
| [Colored background](#colored-background) | If thresholds are set, then the field background is displayed in the appropriate threshold color. |
|
||||
| [Gauge](#gauge) | Cells can be displayed as a graphical gauge, with several different presentation types. You can set the [Gauge display mode](#gauge-display-mode) and the [Value display](#value-display) options. |
|
||||
<!-- prettier-ignore-start -->
|
||||
| Cell type | Description |
|
||||
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Auto](#auto) | A basic text and number cell. |
|
||||
| [Sparkline](#sparkline) | Shows values rendered as a sparkline. |
|
||||
| [Colored text](#colored-text) | If thresholds, value mappings, or color schemes are set, then the cell text is displayed in the appropriate color. |
|
||||
| [Colored background](#colored-background) | If thresholds, value mappings, or color schemes are set, then the cell background is displayed in the appropriate color. |
|
||||
| [Gauge](#gauge) | Values are displayed as a horizontal bar gauge. You can set the [Gauge display mode](#gauge-display-mode) and the [Value display](#value-display) options. |
|
||||
| Data links | If you've configured data links, when the cell type is **Auto**, the cell text becomes clickable. If you change the cell type to **Data links**, the cell text reflects the titles of the configured data links. To control the application of data link text more granularly, use a **Cell option > Cell type > Data links** field override. |
|
||||
| [JSON View](#json-view) | Shows values formatted as code. |
|
||||
| [Image](#image) | If the field value is an image URL or a base64 encoded image, the table displays the image. |
|
||||
| [Actions](#actions) | The cell displays a button that triggers a basic, unauthenticated API call when clicked. |
|
||||
| [JSON View](#json-view) | Shows values formatted as code. |
|
||||
| [Image](#image) | Displays an image when the value is a URL or a base64 encoded image. |
|
||||
| [Actions](#actions) | The cell displays a button that triggers a basic, unauthenticated API call when clicked. |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
##### Sparkline
|
||||
#### Auto
|
||||
|
||||
This is a basic text and number cell.
|
||||
|
||||
It has the following cell options:
|
||||
|
||||
{{< docs/shared lookup="visualizations/cell-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
#### Sparkline
|
||||
|
||||
This cell type shows values rendered as a sparkline.
|
||||
To show sparklines on data with multiple time series, use the [Time series to table transformation](ref:time-series-to-table-transformation) to process it into a format the table can show.
|
||||
|
||||

|
||||
|
||||
You can customize sparklines with many of the same options as the [time series visualization](ref:time-series-panel) including line style and width, fill opacity, gradient mode, and more.
|
||||
You can also change the color of the sparkline by updating the [color scheme](ref:color-scheme) in the **Standard options** section of the panel configuration.
|
||||
The sparkline cell type options are described in the following table.
|
||||
For more detailed information about all of the sparkline styling options (except **Hide value**), refer to the [time series graph styles documentation](ref:graph-styles).
|
||||
|
||||
##### Colored text
|
||||
<!-- prettier-ignore-start -->
|
||||
| Option | Description |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| Hide value | Toggle the switch on or off to display or hide the cell value on the sparkline. |
|
||||
| Style | Choose whether to display your time-series data as **Lines**, **Bars**, or **Points**. You can use overrides to combine multiple styles in the same graph. |
|
||||
| Line interpolation | How the graph interpolates the series line. Choose from:<ul><li>**Linear** - Points are joined by straight lines.</li><li>**Smooth** - Points are joined by curved lines that smooths transitions between points.</li><li>**Step before** - The line is displayed as steps between points. Points are rendered at the end of the step.</li><li>**Step after** - The line is displayed as steps between points. Points are rendered at the beginning of the step.</li></ul> |
|
||||
| Line width | The thickness of the series lines or the outline for bars using the **Line width** slider. |
|
||||
| Fill opacity | The series area fill color using the **Fill opacity** slider. |
|
||||
| Gradient mode | Gradient mode controls the gradient fill, which is based on the series color. Gradient appearance is influenced by the **Fill opacity** setting. To change the color, use the standard color scheme field option. For more information, refer to [Color scheme](ref:color-scheme). Choose from:<ul><li>**None** - No gradient fill. This is the default setting.</li><li>**Opacity** - An opacity gradient where the opacity of the fill increases as y-axis values increase.</li><li>**Hue** - A subtle gradient that's based on the hue of the series color.</li></ul> |
|
||||
| Line style | Choose from:<ul><li>**Solid**</li><li>**Dash** - Select the length and gap for the line dashes. Default dash spacing is 10, 10.</li><li>**Dots** - Select the gap for the dot spacing. Default dot spacing is 0, 10.</li></ul> |
|
||||
| Connect null values | How null values, which are gaps in the data, appear on the graph. Null values can be connected to form a continuous line or set to a threshold above which gaps in the data are no longer connected. Choose from:<ul><li>**Never** - Time series data points with gaps in the data are never connected.</li><li>**Always** - Time series data points with gaps in the data are always connected.</li><li>**Threshold** - Specify a threshold above which gaps in the data are no longer connected. This can be useful when the connected gaps in the data are of a known size or within a known range, and gaps outside this range should no longer be connected.</li></ul> |
|
||||
| Show points | Whether to show data points to lines or bars. Choose from: <ul><li>**Auto** - Grafana determines a point's visibility based on the density of the data. If the density is low, then points appear.</li><li>**Always** - Show the points regardless of how dense the dataset is.</li><li>**Never** - Don't show points.</li></ul> |
|
||||
| Point size | Set the size of the points, from 1 to 40 pixels in diameter. |
|
||||
| Bar alignment | Set the position of the bar relative to a data point. |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
If thresholds are set, with this cell type, the field text is displayed in the appropriate threshold color.
|
||||
#### Colored text
|
||||
|
||||
If thresholds, value mappings, or color schemes are set, the cell text is displayed in the appropriate color.
|
||||
|
||||

|
||||
|
||||
{{< admonition type="note" >}}
|
||||
This is an experimental feature.
|
||||
{{< /admonition >}}
|
||||
The colored text cell type has the following options:
|
||||
|
||||
##### Colored background
|
||||
{{< docs/shared lookup="visualizations/cell-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
If thresholds are set, with this cell type, the field background is displayed in the appropriate threshold color.
|
||||
#### Colored background
|
||||
|
||||
If thresholds, value mappings, or color schemes are set, the cell background is displayed in the appropriate color.
|
||||
|
||||

|
||||
|
||||
- **Background display mode** - Choose between **Basic** and **Gradient**.
|
||||
- **Apply to entire row** - Toggle the switch on to apply the background color that's configured for the cell to the whole row.
|
||||
You can also set background cell color by row:
|
||||
|
||||

|
||||
|
||||
##### Gauge
|
||||
The colored background cell type has the following options:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
| Background display mode | Choose between **Basic** and **Gradient**. |
|
||||
| Apply to entire row | Toggle the switch on to apply the background color that's configured for the cell to the whole row. |
|
||||
| Wrap text | <p>Toggle the **Wrap text** switch to wrap text in the cell that contains the longest content in your table. To wrap the text _in a specific column only_, use a **Fields with name** [field override](ref:field-override), select the **Cell options > Cell type** override property, and toggle on the **Wrap text** switch.</p><p>Text wrapping is in [public preview](https://grafana.com/docs/release-life-cycle/#public-preview), however, it’s available to use by default.</p> |
|
||||
| Cell value inspect | <p>Enables value inspection from table cells. When the switch is toggled on, clicking the inspect icon in a cell opens the **Inspect value** drawer which contains two tabs: **Plain text** and **Code editor**.</p><p>Grafana attempts to automatically detect the type of data in the cell and opens the drawer with the associated tab showing. However, you can switch back and forth between tabs.</p> |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- The wrap text and cell value inspect descriptions above should be copied from docs/sources/shared/visualizations/cell-options.md -->
|
||||
|
||||
#### Gauge
|
||||
|
||||
With this cell type, cells can be displayed as a graphical gauge, with several different presentation types controlled by the [gauge display mode](#gauge-display-mode) and the [value display](#value-display).
|
||||
|
||||
@@ -283,53 +323,58 @@ The maximum and minimum values of the gauges are configured automatically from t
|
||||
If you don't want the max/min values to be pulled from the whole dataset, you can configure them for each column using [field overrides](#field-overrides).
|
||||
{{< /admonition >}}
|
||||
|
||||
###### Gauge display mode
|
||||
##### Gauge display mode
|
||||
|
||||
You can set three gauge display modes.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
| Basic | Shows a simple gauge with the threshold levels defining the color of gauge. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-gauge-mode-basic-v11.3.png" alt="Table cell with basic gauge mode" >}} |
|
||||
| Gradient | The threshold levels define a gradient. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-gauge-mode-gradient-v11.3.png" alt="Table cell with gradient gauge mode" >}} |
|
||||
| Retro LCD | The gauge is split up in small cells that are lit or unlit. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-gauge-mode-retro-v11.3.png" alt="Table cell with retro LCD gauge mode" >}} |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
###### Value display
|
||||
##### Value display
|
||||
|
||||
Labels displayed alongside of the gauges can be set to be colored by value, match the theme text color, or be hidden.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
| Value color | Labels are colored by value. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-labels-value-color-v11.3.png" alt="Table with labels in value color" >}} |
|
||||
| Text color | Labels match the theme text color. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-labels-text-color-v11.3.png" alt="Table with labels in theme color" >}} |
|
||||
| Hidden | Labels are hidden. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-labels-hidden-v11.3.png" alt="Table with labels hidden" >}} |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
##### JSON View
|
||||
#### JSON View
|
||||
|
||||
This cell type shows values formatted as code.
|
||||
If a value is an object the JSON view allowing browsing the JSON object will appear on hover.
|
||||
|
||||
{{< figure src="/static/img/docs/tables/json-view.png" max-width="350px" alt="JSON view" class="docs-image--no-shadow" >}}
|
||||
|
||||
##### Image
|
||||
For the JSON view cell type, you can set enable **Cell value inspect**.
|
||||
This enables value inspection from table cells.
|
||||
When the switch is toggled on, clicking the inspect icon in a cell opens the **Inspect value** drawer which contains two tabs: **Plain text** and **Code editor**.
|
||||
|
||||
Grafana attempts to automatically detect the type of data in the cell and opens the drawer with the associated tab showing.
|
||||
However, you can switch back and forth between tabs
|
||||
|
||||
#### Image
|
||||
|
||||
If you have a field value that is an image URL or a base64 encoded image, this cell type displays it as an image.
|
||||
|
||||

|
||||
|
||||
Set the following options:
|
||||
It has the following options:
|
||||
|
||||
- **Alt text** - Set the alternative text of an image. The text will be available for screen readers and in cases when images can't be loaded.
|
||||
- **Title text** - Set the text that's displayed when the image is hovered over with a cursor.
|
||||
| Option | Description |
|
||||
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Alt text | Set the alternative text of an image. The text will be available for screen readers and in cases when images can't be loaded. |
|
||||
| Title text | Set the text that's displayed when the image is hovered over with a cursor. |
|
||||
|
||||
##### Actions
|
||||
#### Actions
|
||||
|
||||
The cell displays a button that triggers a basic, unauthenticated API call when clicked.
|
||||
Configure the API call with the following options:
|
||||
@@ -343,34 +388,8 @@ Configure the API call with the following options:
|
||||
| Query parameters | Enter as many **Key**, **Value** pairs as you need. |
|
||||
| Header parameters | Enter as many **Key**, **Value** pairs as you need. |
|
||||
| Payload | Enter the body of the API call. |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
#### Wrap text
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Text wrapping is in [public preview](https://grafana.com/docs/release-life-cycle/#public-preview), however, it’s available to use by default.
|
||||
We’d love hear from you about how this new feature is working. To provide feedback, you can open an issue in the [Grafana GitHub repository](https://github.com/grafana/grafana).
|
||||
{{< /admonition >}}
|
||||
|
||||
Toggle the **Wrap text** switch to wrap text in the cell that contains the longest content in your table.
|
||||
|
||||
To wrap the text _in a specific column only_, use a **Fields with name** [field override](ref:field-override), select the **Cell options > Cell type** override property, and toggle on the **Wrap text** switch.
|
||||
|
||||
This option is available for the following cell types: **Auto**, **Colored text**, and **Colored background**.
|
||||
|
||||
#### Cell value inspect
|
||||
|
||||
Enables value inspection from table cells. When the **Cell inspect value** switch is toggled on, clicking the inspect icon in a cell opens the **Inspect value** drawer.
|
||||
|
||||
The **Inspect value** drawer has two tabs, **Plain text** and **Code editor**.
|
||||
Grafana attempts to automatically detect the type of data in the cell and opens the drawer with the associated tab showing.
|
||||
However, you can switch back and forth between tabs.
|
||||
|
||||
This option is available for the following cell types: **Auto**, **Colored text**, **Colored background**, and **JSON View**.
|
||||
|
||||
If you want to apply this setting to only some fields instead of all fields, you can do so using the **Cell options > Cell value inspect** field override.
|
||||
|
||||
### Standard options
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
@@ -35,7 +35,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
|
||||
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
|
||||
| `unifiedRequestLog` | Writes error logs to the request logger | Yes |
|
||||
| `pluginsDetailsRightPanel` | Enables right panel for the plugins details page | Yes |
|
||||
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
|
||||
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
|
||||
| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers | Yes |
|
||||
@@ -107,6 +106,7 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `elasticsearchCrossClusterSearch` | Enables cross cluster search in the Elasticsearch datasource |
|
||||
| `alertRuleRestore` | Enables the alert rule restore feature |
|
||||
| `azureMonitorLogsBuilderEditor` | Enables the logs builder mode for the Azure Monitor data source |
|
||||
| `localeFormatPreference` | Specifies the locale so the correct format for numbers and dates can be shown |
|
||||
| `logsPanelControls` | Enables a control component for the logs panel in Explore |
|
||||
|
||||
## Development feature toggles
|
||||
|
||||
@@ -59,11 +59,16 @@ You can update your settings by using a configuration file, see [default.json](h
|
||||
You can volume mount your custom configuration file when starting the docker container:
|
||||
|
||||
```bash
|
||||
docker run -d --name=renderer --network=host -v /some/path/config.json:/usr/src/app/config.json grafana/grafana-image-renderer:latest
|
||||
docker run -d --name=renderer --network=host -v /some/path/config.json:/home/nonroot/config.json grafana/grafana-image-renderer:latest
|
||||
```
|
||||
|
||||
You can see a docker-compose example using a custom configuration file [here](https://github.com/grafana/grafana-image-renderer/tree/master/devenv/docker/custom-config).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The configuration files were located in `/usr/src/app` up until v4.0.0 and later.
|
||||
After this point, they are located in `/home/nonroot`.
|
||||
{{< /admonition >}}
|
||||
|
||||
### Security
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
@@ -61,49 +61,8 @@ ldd chrome-headless-shell/linux-132.0.6781.0/chrome-headless-shell-linux64/chrom
|
||||
...
|
||||
```
|
||||
|
||||
**Ubuntu:**
|
||||
|
||||
On Ubuntu 18.10 the following dependencies are required for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libx11-6 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrender1 libxtst6 libglib2.0-0 libnss3 libcups2 libdbus-1-3 libxss1 libxrandr2 libgtk-3-0 libasound2 libxcb-dri3-0 libgbm1 libxshmfence1
|
||||
```
|
||||
|
||||
**Debian:**
|
||||
|
||||
On Debian 9 (Stretch) the following dependencies are required for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libx11 libcairo libcairo2 libxtst6 libxcomposite1 libx11-xcb1 libxcursor1 libxdamage1 libnss3 libcups libcups2 libxss libxss1 libxrandr2 libasound2 libatk1.0-0 libatk-bridge2.0-0 libpangocairo-1.0-0 libgtk-3-0 libgbm1 libxshmfence1
|
||||
```
|
||||
|
||||
On Debian 10 (Buster) the following dependencies are required for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libxdamage1 libxext6 libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 libasound2 libatk1.0-0 libatk-bridge2.0-0 libpangocairo-1.0-0 libpango-1.0-0 libcairo2 libatspi2.0-0 libgtk3.0-cil libgdk3.0-cil libx11-xcb-dev libgbm1 libxshmfence1
|
||||
```
|
||||
|
||||
**Centos:**
|
||||
|
||||
On a minimal CentOS 7 installation, the following dependencies are required for the image rendering to function:
|
||||
|
||||
```bash
|
||||
libXcomposite libXdamage libXtst cups libXScrnSaver pango atk adwaita-cursor-theme adwaita-icon-theme at at-spi2-atk at-spi2-core cairo-gobject colord-libs dconf desktop-file-utils ed emacs-filesystem gdk-pixbuf2 glib-networking gnutls gsettings-desktop-schemas gtk-update-icon-cache gtk3 hicolor-icon-theme jasper-libs json-glib libappindicator-gtk3 libdbusmenu libdbusmenu-gtk3 libepoxy liberation-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts libgusb libindicator-gtk3 libmodman libproxy libsoup libwayland-cursor libwayland-egl libxkbcommon m4 mailx nettle patch psmisc redhat-lsb-core redhat-lsb-submod-security rest spax time trousers xdg-utils xkeyboard-config alsa-lib
|
||||
```
|
||||
|
||||
On a minimal CentOS 8 installation, the following dependencies are required for the image rendering to function:
|
||||
|
||||
```bash
|
||||
libXcomposite libXdamage libXtst cups libXScrnSaver pango atk adwaita-cursor-theme adwaita-icon-theme at at-spi2-atk at-spi2-core cairo-gobject colord-libs dconf desktop-file-utils ed emacs-filesystem gdk-pixbuf2 glib-networking gnutls gsettings-desktop-schemas gtk-update-icon-cache gtk3 hicolor-icon-theme jasper-libs json-glib libappindicator-gtk3 libdbusmenu libdbusmenu-gtk3 libepoxy liberation-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts libgusb libindicator-gtk3 libmodman libproxy libsoup libwayland-cursor libwayland-egl libxkbcommon m4 mailx nettle patch psmisc redhat-lsb-core redhat-lsb-submod-security rest spax time trousers xdg-utils xkeyboard-config alsa-lib libX11-xcb
|
||||
```
|
||||
|
||||
**RHEL:**
|
||||
|
||||
On a minimal RHEL 8 installation, the following dependencies are required for the image rendering to function:
|
||||
|
||||
```bash
|
||||
linux-vdso.so.1 libdl.so.2 libpthread.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 libnss3.so libnssutil3.so libsmime3.so libnspr4.so libatk-1.0.so.0 libatk-bridge-2.0.so.0 libcups.so.2 libgio-2.0.so.0 libdrm.so.2 libdbus-1.so.3 libexpat.so.1 libxcb.so.1 libxkbcommon.so.0 libm.so.6 libX11.so.6 libXcomposite.so.1 libXdamage.so.1 libXext.so.6 libXfixes.so.3 libXrandr.so.2 libgbm.so.1 libpango-1.0.so.0 libcairo.so.2 libasound.so.2 libatspi.so.0 libgcc_s.so.1 libc.so.6 /lib64/ld-linux-x86-64.so.2 libgnutls.so.30 libpcre.so.1 libffi.so.6 libplc4.so libplds4.so librt.so.1 libgmodule-2.0.so.0 libgssapi_krb5.so.2 libkrb5.so.3 libk5crypto.so.3 libcom_err.so.2 libavahi-common.so.3 libavahi-client.so.3 libcrypt.so.1 libz.so.1 libselinux.so.1 libresolv.so.2 libmount.so.1 libsystemd.so.0 libXau.so.6 libXrender.so.1 libthai.so.0 libfribidi.so.0 libpixman-1.so.0 libfontconfig.so.1 libpng16.so.16 libxcb-render.so.0 libidn2.so.0 libunistring.so.2 libtasn1.so.6 libnettle.so.6 libhogweed.so.4 libgmp.so.10 libkrb5support.so.0 libkeyutils.so.1 libpcre2-8.so.0 libuuid.so.1 liblz4.so.1 libgcrypt.so.20 libbz2.so.1
|
||||
```
|
||||
You can find a reference to all the relevant Debian packages for the service to function [in the Dockerfile](https://github.com/grafana/grafana-image-renderer/blob/master/Dockerfile).
|
||||
If you are using an operating system that is not Debian 12, you should look up what each of those packages are called on your system.
|
||||
|
||||
## Certificate signed by internal certificate authorities
|
||||
|
||||
@@ -127,6 +86,9 @@ If this happens, then you have to add the certificate to the trust store. If you
|
||||
[root@server ~]# chown -R grafana: /usr/share/grafana/.pki/nssdb
|
||||
```
|
||||
|
||||
You may also have to use other tooling than `certutil`, such as `update-ca-certificates` and its accompanying paths.
|
||||
This depends on the Linux distribution you use; distributions often have a wiki with this type of information.
|
||||
|
||||
**Windows:**
|
||||
|
||||
```
|
||||
@@ -138,17 +100,25 @@ certutil –addstore "Root" <path>/internal-root-ca.crt.pem
|
||||
```Dockerfile
|
||||
FROM grafana/grafana-image-renderer:latest
|
||||
|
||||
# Elevate our permissions to access system resources.
|
||||
USER root
|
||||
|
||||
RUN apk add --no-cache nss-tools
|
||||
RUN mkdir -p /usr/local/share/ca-certificates/
|
||||
# Convert from .pem to .crt
|
||||
RUN openssl x509 -inform PEM -in rootCA.pem -out /usr/local/share/ca-certificates/rootCA.crt
|
||||
|
||||
USER grafana
|
||||
# Regenerate the CA certificates in the container.
|
||||
RUN update-ca-certificates --fresh
|
||||
|
||||
COPY internal-root-ca.crt.pem /etc/pki/tls/certs/internal-root-ca.crt.pem
|
||||
RUN mkdir -p /home/grafana/.pki/nssdb
|
||||
RUN certutil -d sql:/home/grafana/.pki/nssdb -A -n internal-root-ca -t C -i /etc/pki/tls/certs/internal-root-ca.crt.pem
|
||||
# Reassume the nonroot user for the service execution.
|
||||
USER nonroot
|
||||
```
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The container image was based on Alpine until v4.0.0.
|
||||
After this point, it is based on distroless Debian.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Custom Chrome/Chromium
|
||||
|
||||
As a last resort, if you already have [Chrome](https://www.google.com/chrome/) or [Chromium](https://www.chromium.org/)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Cell options
|
||||
---
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
| Wrap text | <p>Toggle the **Wrap text** switch to wrap text in the cell that contains the longest content in your table. To wrap the text _in a specific column only_, use a **Fields with name** [field override](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/configure-overrides/), select the **Cell options > Cell type** override property, and toggle on the **Wrap text** switch.</p><p>Text wrapping is in [public preview](https://grafana.com/docs/release-life-cycle/#public-preview), however, it’s available to use by default.</p> |
|
||||
| Cell value inspect | <p>Enables value inspection from table cells. When the switch is toggled on, clicking the inspect icon in a cell opens the **Inspect value** drawer which contains two tabs: **Plain text** and **Code editor**.</p><p>Grafana attempts to automatically detect the type of data in the cell and opens the drawer with the associated tab showing. However, you can switch back and forth between tabs.</p> |
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
description: Guide for upgrading to Grafana v12.1
|
||||
keywords:
|
||||
- grafana
|
||||
- configuration
|
||||
- documentation
|
||||
- upgrade
|
||||
- '12.1'
|
||||
title: Upgrade to Grafana v12.1
|
||||
menuTitle: Upgrade to v12.1
|
||||
weight: 499
|
||||
---
|
||||
|
||||
# Upgrade to Grafana v12.1
|
||||
|
||||
{{< docs/shared lookup="upgrade/intro_2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
{{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="<GRAFANA_VERSION>" leveloffset="+1" >}}
|
||||
|
||||
{{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Technical notes
|
||||
@@ -46,7 +46,7 @@ We provide release documentation in multiple places to address different needs:
|
||||
|
||||
## When to expect releases
|
||||
|
||||
Currently, Grafana is on a monthly release cycle. Here’s a look at scheduled releases for 2025:
|
||||
Grafana currently follows a monthly release schedule. Below are the planned releases for 2025, though these dates may be subject to change:
|
||||
|
||||
| **Release date** | **Grafana versions** | **Release type** |
|
||||
| ---------------- | ------------------------- | ---------------- |
|
||||
@@ -110,14 +110,14 @@ Here is an overview of version support through 2026:
|
||||
| 11.0.x | May 14, 2024 | February 14, 2025 | Not Supported |
|
||||
| 11.1.x | June 25, 2024 | April 23, 2025 | Not Supported |
|
||||
| 11.2.x | August 27, 2024 | May 27, 2025 | Not Supported |
|
||||
| 11.3.x | October 22, 2024 | July 22, 2025 | Security & Critical Bugs Only |
|
||||
| 11.3.x | October 22, 2024 | July 22, 2025 | Not Supported |
|
||||
| 11.4.x | December 5, 2024 | September 5, 2025 | Security & Critical Bugs Only |
|
||||
| 11.5.x | January 28, 2025 | October 28, 2025 | Security & Critical Bugs Only |
|
||||
| 11.6.x (Last minor of 11) | March 25, 2025 | May 25, 2026 | Security & Critical Bugs Only |
|
||||
| 12.0.x | May 5, 2025 | February 5, 2026 | Full Support until next minor |
|
||||
| 12.0.x | May 5, 2025 | February 5, 2026 | Security & Critical Bugs Only |
|
||||
| 12.1.x | July 22, 2025 | April 22, 2026 | Full Support until next minor |
|
||||
| 12.2.x | September 23, 2025 | June 23, 2026 | Full Support until next minor |
|
||||
| 12.3.x | November 18, 2025 | August 18, 2026 | Full Support until next minor |
|
||||
| 12.2.x | September 23, 2025 | June 23, 2026 | Yet to be released |
|
||||
| 12.3.x | November 18, 2025 | August 18, 2026 | Yet to be released |
|
||||
|
||||
## How are these versions supported?
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ For a complete list of every change, with links to pull requests and related iss
|
||||
|
||||
## Grafana 12
|
||||
|
||||
- [What's new in 12.1](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v12-1)
|
||||
- [What's new in 12.0](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v12-0)
|
||||
|
||||
## Grafana 11
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
description: Feature and improvement highlights for Grafana v12.1
|
||||
keywords:
|
||||
- grafana
|
||||
- new
|
||||
- documentation
|
||||
- '12.1'
|
||||
- release notes
|
||||
labels:
|
||||
products:
|
||||
- cloud
|
||||
- enterprise
|
||||
- oss
|
||||
title: What's new in Grafana v12.1
|
||||
posts:
|
||||
- title: Data sources
|
||||
items:
|
||||
- whats-new/2025-06-11-logicmonitor-enterprise-data-source-for-grafana.md
|
||||
- whats-new/2025-06-20-support-for-service-account-impersonation-in-bigquery.md
|
||||
- whats-new/2025-07-08-keep-instances-running-smoothly-with-grafana-advisor.md
|
||||
- title: Alerting
|
||||
items:
|
||||
- whats-new/2025-07-11-alert-rule-list-page-updates.md
|
||||
- whats-new/2025-07-09-active-time-intervals-in-grafana-alerting.md
|
||||
- whats-new/2025-07-14-add-ability-to-import-rules-to-gma-from-prometheus-yaml.md
|
||||
- title: Dashboards and visualizations
|
||||
items:
|
||||
- whats-new/2025-06-30-transformations-regression-analysis.md
|
||||
- whats-new/2025-07-14-custom-variable-support-in-visualization-actions.md
|
||||
- whats-new/2025-07-10-server-configurable-quick-time-ranges-for-dashboards.md
|
||||
- whats-new/2025-07-14-enhanced-custom-currency-format-display-exact-financial-values.md
|
||||
- title: Authentication and authorization
|
||||
items:
|
||||
- whats-new/2025-07-14-entra-id-workload-identity-support.md
|
||||
whats_new_grafana_version: 12.1
|
||||
weight: -50
|
||||
---
|
||||
|
||||
# What’s new in Grafana v12.1
|
||||
|
||||
It’s 12.1 time! We’re really excited about GA for a new alert rule page that makes it easier to find what you need quickly, as well as the regression analysis transformation, helping you predict future data values or estimate missing data points that might not be exactly represented in the original dataset. Also, visualization actions now support custom variables. When triggered, actions prompt you to input whatever custom variable was defined, allowing you to tailor requests in real time without modifying dashboard configuration. This is super helpful for when you’re triggering alerts, filtering API calls, or sending user-defined parameters to external systems. And you can try out Grafana Advisor, which automatically detects plugin, data source, and SSO issues, keeping your Grafana instance healthy and secure.
|
||||
|
||||
Speaking of security, Grafana now supports Entra Workload Identity, simplifying OAuth and increasing security for instances using Microsoft Azure. Thanks to community contributor [mehighlow](https://github.com/mehighlow) for this feature!
|
||||
|
||||
We have one more community contributor to thank for this release. [Chris Hodges](https://github.com/chodges15) delivered server-configurable quick time ranges for dashboards. Now you can define custom time range presets for the time picker on dashboards, perfect for teams that routinely analyze specific, context-driven time windows.
|
||||
|
||||
Keep reading to learn about what else we have in store for 12.1.
|
||||
|
||||
<!-- {{< youtube id=Umy-kCKkMQM >}} -->
|
||||
|
||||
For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v12.1, check out our [Upgrade Guide](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/upgrade-guide/upgrade-v12.1/).
|
||||
|
||||
{{< docs/whats-new >}}
|
||||
+4
-2
@@ -51,8 +51,10 @@ test.describe(
|
||||
|
||||
// Get the tooltip ID from the aria-describedby attribute
|
||||
const tooltipId = await descriptionIcon.getAttribute('aria-describedby');
|
||||
const tooltip = page.locator(`[id="${tooltipId}"]`);
|
||||
await expect(tooltip).toHaveText(`${newDescription}\n`);
|
||||
await expect(async () => {
|
||||
const tooltip = page.locator(`[id="${tooltipId}"]`);
|
||||
await expect(tooltip).toHaveText(`${newDescription}\n`);
|
||||
}).toPass();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -42,6 +42,9 @@ test.describe(
|
||||
await page.getByTestId(selectors.components.TimeZonePicker.containerV2).click();
|
||||
await page.getByRole('option', { name: 'Asia/Tokyo' }).click();
|
||||
await page.getByTestId(selectors.components.UserProfile.preferencesSaveButton).click();
|
||||
// wait for the page to reload before trying to navigate, otherwise this can cause flakes
|
||||
// see e.g. https://github.com/microsoft/playwright/issues/21451#issuecomment-1502251404
|
||||
await page.waitForURL('/profile');
|
||||
|
||||
// Open dashboard with time range from 8th to end of 10th.
|
||||
// Will be Tokyo time because of above preference
|
||||
|
||||
@@ -2,14 +2,20 @@ import { Page, Locator } from '@playwright/test';
|
||||
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
const DASHBOARD_UID = 'dcb9f5e9-8066-4397-889e-864b99555dbb';
|
||||
|
||||
test.use({
|
||||
viewport: { width: 1600, height: 1080 },
|
||||
viewport: { width: 2000, height: 1080 },
|
||||
featureToggles: {
|
||||
tableNextGen: true,
|
||||
},
|
||||
});
|
||||
|
||||
// helper utils
|
||||
const waitForTableLoad = async (loc: Page | Locator) => {
|
||||
await expect(loc.locator('.rdg')).toBeVisible();
|
||||
};
|
||||
|
||||
const getCell = async (loc: Page | Locator, rowIdx: number, colIdx: number) =>
|
||||
loc
|
||||
.getByRole('row')
|
||||
@@ -22,6 +28,24 @@ const getCellHeight = async (loc: Page | Locator, rowIdx: number, colIdx: number
|
||||
return (await cell.boundingBox())?.height ?? 0;
|
||||
};
|
||||
|
||||
const getColumnIdx = async (loc: Page | Locator, columnName: string) => {
|
||||
// find the index of the column "Long text." The kitchen sink table will change over time, but
|
||||
// we can just find the column programatically and use it throughout the test.
|
||||
let result = -1;
|
||||
const colCount = await loc.getByRole('columnheader').count();
|
||||
for (let colIdx = 0; colIdx < colCount; colIdx++) {
|
||||
const cell = await getCell(loc, 0, colIdx);
|
||||
if ((await cell.textContent()) === columnName) {
|
||||
result = colIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result === -1) {
|
||||
throw new Error(`Could not find the "${columnName}" column in the table`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
test.describe(
|
||||
'Panels test: Table - Kitchen Sink',
|
||||
{
|
||||
@@ -30,7 +54,7 @@ test.describe(
|
||||
() => {
|
||||
test('Tests word wrap, hover overflow, and cell inspect', async ({ gotoDashboardPage, selectors, page }) => {
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -38,22 +62,28 @@ test.describe(
|
||||
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Table - Kitchen Sink'))
|
||||
).toBeVisible();
|
||||
|
||||
// to avoid a race condition when counting up , wait for react-data-grid to finish rendering.
|
||||
await waitForTableLoad(page);
|
||||
|
||||
const longTextColIdx = await getColumnIdx(page, 'Long Text');
|
||||
|
||||
// text wrapping is enabled by default on this panel.
|
||||
await expect(getCellHeight(page, 1, 5)).resolves.toBeGreaterThan(100);
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeGreaterThan(100);
|
||||
|
||||
// toggle the lorem ipsum column's wrap text toggle and confirm that the height shrinks.
|
||||
await dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Wrap text'))
|
||||
.last()
|
||||
.click();
|
||||
await expect(getCellHeight(page, 1, 5)).resolves.toBeLessThan(100);
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeLessThan(100);
|
||||
|
||||
// test that hover overflow works.
|
||||
const loremIpsumCell = await getCell(page, 1, 5);
|
||||
const loremIpsumCell = await getCell(page, 1, longTextColIdx);
|
||||
await loremIpsumCell.scrollIntoViewIfNeeded();
|
||||
await loremIpsumCell.hover();
|
||||
await expect(getCellHeight(page, 1, 5)).resolves.toBeGreaterThan(100);
|
||||
await (await getCell(page, 1, 6)).hover();
|
||||
await expect(getCellHeight(page, 1, 5)).resolves.toBeLessThan(100);
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeGreaterThan(100);
|
||||
await (await getCell(page, 1, longTextColIdx + 1)).hover();
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeLessThan(100);
|
||||
|
||||
// enable cell inspect, confirm that hover no longer triggers.
|
||||
await dashboardPage
|
||||
@@ -64,7 +94,7 @@ test.describe(
|
||||
.locator('label[for="custom.inspect"]')
|
||||
.click();
|
||||
await loremIpsumCell.hover();
|
||||
await expect(getCellHeight(page, 1, 5)).resolves.toBeLessThan(100);
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeLessThan(100);
|
||||
|
||||
// click cell inspect, check that cell inspection pops open in the side as we'd expect.
|
||||
await loremIpsumCell.getByLabel('Inspect value').click();
|
||||
@@ -75,7 +105,7 @@ test.describe(
|
||||
|
||||
test('Tests visibility and display name via overrides', async ({ gotoDashboardPage, selectors, page }) => {
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -107,7 +137,7 @@ test.describe(
|
||||
// hashtag testing pyramid.
|
||||
test('Tests sorting by column', async ({ gotoDashboardPage, selectors, page }) => {
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -132,7 +162,7 @@ test.describe(
|
||||
|
||||
test('Tests filtering within a column', async ({ gotoDashboardPage, selectors, page }) => {
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -140,10 +170,14 @@ test.describe(
|
||||
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Table - Kitchen Sink'))
|
||||
).toBeVisible();
|
||||
|
||||
const stateColumnHeader = page.getByRole('columnheader').filter({ hasText: 'Info' });
|
||||
await waitForTableLoad(page);
|
||||
|
||||
const infoColumnIdx = await getColumnIdx(page, 'Info');
|
||||
|
||||
const stateColumnHeader = page.getByRole('columnheader').nth(infoColumnIdx);
|
||||
|
||||
// get the first value in the "State" column, filter it out, then check that it went away.
|
||||
const firstStateValue = (await (await getCell(page, 1, 1)).textContent())!;
|
||||
const firstStateValue = (await (await getCell(page, 1, infoColumnIdx)).textContent())!;
|
||||
await stateColumnHeader
|
||||
.getByTestId(selectors.components.Panels.Visualization.TableNG.Filters.HeaderButton)
|
||||
.click();
|
||||
@@ -162,7 +196,7 @@ test.describe(
|
||||
await expect(filterContainer).not.toBeVisible();
|
||||
|
||||
// did it actually filter out our value?
|
||||
await expect(getCell(page, 1, 1)).resolves.not.toHaveText(firstStateValue);
|
||||
await expect(getCell(page, 1, infoColumnIdx)).resolves.not.toHaveText(firstStateValue);
|
||||
});
|
||||
|
||||
test('Tests pagination, row height adjustment', async ({ gotoDashboardPage, selectors, page }) => {
|
||||
@@ -178,7 +212,7 @@ test.describe(
|
||||
};
|
||||
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -251,12 +285,12 @@ test.describe(
|
||||
await page.getByRole('dialog').locator('#data-link-input [contenteditable="true"]').focus();
|
||||
await page.getByRole('dialog').locator('#data-link-input [contenteditable="true"]').fill(url);
|
||||
await page.getByRole('dialog').locator('#data-link-input [contenteditable="true"]').blur();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('dialog').locator('button[aria-disabled="false"]').filter({ hasText: 'Save' }).click();
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible();
|
||||
};
|
||||
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '1' }),
|
||||
});
|
||||
|
||||
@@ -271,8 +305,12 @@ test.describe(
|
||||
.last()
|
||||
.click();
|
||||
|
||||
const infoColumnIdx = await getColumnIdx(page, 'Info');
|
||||
const pillColIdx = await getColumnIdx(page, 'Pills');
|
||||
const dataLinkColIdx = await getColumnIdx(page, 'Data Link');
|
||||
|
||||
// Info column has a single DataLink by default.
|
||||
const infoCell = await getCell(page, 1, 1);
|
||||
const infoCell = await getCell(page, 1, infoColumnIdx);
|
||||
await expect(infoCell.locator('a')).toBeVisible();
|
||||
expect(infoCell.locator('a')).toHaveAttribute('href');
|
||||
expect(infoCell.locator('a')).not.toHaveAttribute('aria-haspopup');
|
||||
@@ -283,6 +321,12 @@ test.describe(
|
||||
// add a DataLink to the whole table, all cells will now have a single link.
|
||||
const colCount = await page.getByRole('row').nth(1).getByRole('gridcell').count();
|
||||
for (let colIdx = 0; colIdx < colCount; colIdx++) {
|
||||
// - pills column currently does not support DataLinks.
|
||||
// - we don't apply DataLinks to the DataLinks column itself, since they're rendered inside.
|
||||
if (colIdx === pillColIdx || colIdx === dataLinkColIdx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const cell = await getCell(page, 1, colIdx);
|
||||
await expect(cell.locator('a')).toBeVisible();
|
||||
expect(cell.locator('a')).toHaveAttribute('href');
|
||||
@@ -297,12 +341,18 @@ test.describe(
|
||||
// loop thru the columns, click the links, observe that the tooltip appears, and close the tooltip.
|
||||
for (let colIdx = 0; colIdx < colCount; colIdx++) {
|
||||
const cell = await getCell(page, 1, colIdx);
|
||||
if (colIdx === 1) {
|
||||
if (colIdx === infoColumnIdx) {
|
||||
// the Info column should still have its single link.
|
||||
expect(cell.locator('a')).not.toHaveAttribute('aria-haspopup', 'menu');
|
||||
continue;
|
||||
}
|
||||
|
||||
// - pills column currently does not support DataLinks.
|
||||
// - we don't apply DataLinks to the DataLinks column itself, since they're rendered inside.
|
||||
if (colIdx === pillColIdx || colIdx === dataLinkColIdx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await cell.locator('a').click({ force: true });
|
||||
await expect(page.getByTestId(selectors.components.DataLinksActionsTooltip.tooltipWrapper)).toBeVisible();
|
||||
|
||||
@@ -316,7 +366,7 @@ test.describe(
|
||||
|
||||
test('Empty Table panel', async ({ gotoDashboardPage, selectors }) => {
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: 'dcb9f5e9-8066-4397-889e-864b99555dbb',
|
||||
uid: DASHBOARD_UID,
|
||||
queryParams: new URLSearchParams({ editPanel: '2' }),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@test-plugins/extensions-test-app",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@test-plugins/grafana-e2etest-datasource",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production",
|
||||
|
||||
@@ -31,7 +31,7 @@ test.describe(
|
||||
await expect(sandboxDiv).toBeHidden();
|
||||
|
||||
const appPage = page.getByTestId('sandbox-app-test-page-one');
|
||||
await expect(appPage).toBeVisible({ timeout: 10000 });
|
||||
await expect(appPage).toBeVisible();
|
||||
});
|
||||
|
||||
test('Loads the app configuration without the sandbox div wrapper', async ({ page }) => {
|
||||
@@ -41,7 +41,7 @@ test.describe(
|
||||
await expect(sandboxDiv).toBeHidden();
|
||||
|
||||
const configPage = page.getByTestId('sandbox-app-test-config-page');
|
||||
await expect(configPage).toBeVisible({ timeout: 10000 });
|
||||
await expect(configPage).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ test.describe(
|
||||
await expect(sandboxDiv).toBeVisible();
|
||||
|
||||
const appPage = page.getByTestId('sandbox-app-test-page-one');
|
||||
await expect(appPage).toBeVisible({ timeout: 10000 });
|
||||
await expect(appPage).toBeVisible();
|
||||
});
|
||||
|
||||
test('Loads the app configuration with the sandbox div wrapper', async ({ page }) => {
|
||||
@@ -69,7 +69,7 @@ test.describe(
|
||||
await expect(sandboxDiv).toBeVisible();
|
||||
|
||||
const configPage = page.getByTestId('sandbox-app-test-config-page');
|
||||
await expect(configPage).toBeVisible({ timeout: 10000 });
|
||||
await expect(configPage).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -410,4 +410,22 @@ module.exports = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'grafana/no-extensions-imports',
|
||||
files: ['**/*.{ts,tsx,js}'],
|
||||
ignores: ['public/app/extensions/**/*'],
|
||||
rules: {
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ['app/extensions', 'app/extensions/*'],
|
||||
message: 'Importing from app/extensions is not allowed',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -104,7 +104,7 @@ require (
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.278.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/loki/v3 v3.2.1 // @grafana/observability-logs
|
||||
github.com/grafana/nanogit v0.0.0-20250717084510-7027b3f0138e // @grafana-app-platform-squad
|
||||
github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0 // @grafana-app-platform-squad
|
||||
github.com/grafana/otel-profiling-go v0.5.1 // @grafana/grafana-backend-group
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // @grafana/observability-traces-and-profiling
|
||||
github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae // @grafana/observability-traces-and-profiling
|
||||
|
||||
@@ -1642,8 +1642,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231124142027-e52380921608 h1:ZYk42718k
|
||||
github.com/grafana/loki/pkg/push v0.0.0-20231124142027-e52380921608/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0=
|
||||
github.com/grafana/loki/v3 v3.2.1 h1:VB7u+KHfvL5aHAxgoVBvz5wVhsdGuqKC7uuOFOOe7jw=
|
||||
github.com/grafana/loki/v3 v3.2.1/go.mod h1:WvdLl6wOS+yahaeQY+xhD2m2XzkHDfKr5FZaX7D/X2Y=
|
||||
github.com/grafana/nanogit v0.0.0-20250717084510-7027b3f0138e h1:IcrC8SqJcNbGlNq0nqptJ4X8pyy21smMaFrhA7DrfYg=
|
||||
github.com/grafana/nanogit v0.0.0-20250717084510-7027b3f0138e/go.mod h1:ToqLjIdvV3AZQa3K6e5m9hy/nsGaUByc2dWQlctB9iA=
|
||||
github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0 h1:cS0SlJGIlZbmDLctNj5vIYGemrJDLy25wwoiIyZWVN8=
|
||||
github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0/go.mod h1:ToqLjIdvV3AZQa3K6e5m9hy/nsGaUByc2dWQlctB9iA=
|
||||
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
|
||||
github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6 h1:oJnbhG6ZNy10AjsgNeAtAKeGHogIGOMfAsBH6fYYa5M=
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
||||
"npmClient": "yarn",
|
||||
"version": "12.1.0-pre"
|
||||
"version": "12.2.0-pre"
|
||||
}
|
||||
|
||||
+8
-7
@@ -3,7 +3,7 @@
|
||||
"license": "AGPL-3.0-only",
|
||||
"private": true,
|
||||
"name": "grafana",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"repository": "github:grafana/grafana",
|
||||
"scripts": {
|
||||
"predev": "./scripts/check-frontend-dev.sh",
|
||||
@@ -30,6 +30,7 @@
|
||||
"e2e:plugin:build:dev": "nx run-many -t dev --projects='@test-plugins/*' --maxParallel=100",
|
||||
"test": "jest --notify --watch",
|
||||
"test:coverage": "jest --coverage",
|
||||
"test:storybook": "yarn workspace @grafana/ui storybook:test",
|
||||
"test:coverage:changes": "jest --coverage --changedSince=origin/main",
|
||||
"test:accessibility-report": "./scripts/generate-a11y-report.sh",
|
||||
"test:ci": "mkdir -p reports/junit && JEST_JUNIT_OUTPUT_DIR=reports/junit jest --ci --reporters=default --reporters=jest-junit -w ${TEST_MAX_WORKERS:-100%} --shard=${TEST_SHARD:-1}/${TEST_SHARD_TOTAL:-1}",
|
||||
@@ -81,7 +82,7 @@
|
||||
"@arethetypeswrong/cli": "^0.18.2",
|
||||
"@babel/core": "7.28.0",
|
||||
"@babel/preset-env": "7.28.0",
|
||||
"@babel/runtime": "7.27.6",
|
||||
"@babel/runtime": "7.28.2",
|
||||
"@betterer/betterer": "5.4.0",
|
||||
"@betterer/cli": "5.4.0",
|
||||
"@crowdin/crowdin-api-client": "^1.42.0",
|
||||
@@ -184,7 +185,7 @@
|
||||
"esbuild": "0.25.8",
|
||||
"esbuild-loader": "4.3.0",
|
||||
"esbuild-plugin-browserslist": "^1.0.0",
|
||||
"eslint": "9.28.0",
|
||||
"eslint": "9.31.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jest": "28.11.0",
|
||||
@@ -201,7 +202,7 @@
|
||||
"eslint-webpack-plugin": "4.2.0",
|
||||
"expose-loader": "5.0.1",
|
||||
"fishery": "^2.2.2",
|
||||
"fork-ts-checker-webpack-plugin": "9.0.2",
|
||||
"fork-ts-checker-webpack-plugin": "9.1.0",
|
||||
"glob": "11.0.3",
|
||||
"html-loader": "5.1.0",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
@@ -271,6 +272,7 @@
|
||||
"@formatjs/intl-durationformat": "^0.7.0",
|
||||
"@glideapps/glide-data-grid": "^6.0.0",
|
||||
"@grafana/alerting": "workspace:*",
|
||||
"@grafana/assistant": "0.0.10",
|
||||
"@grafana/aws-sdk": "0.7.1",
|
||||
"@grafana/azure-sdk": "0.0.7",
|
||||
"@grafana/data": "workspace:*",
|
||||
@@ -370,7 +372,7 @@
|
||||
"moveable": "0.53.0",
|
||||
"nanoid": "^5.0.9",
|
||||
"node-forge": "^1.3.1",
|
||||
"ol": "10.6.0",
|
||||
"ol": "10.6.1",
|
||||
"ol-ext": "4.0.33",
|
||||
"pluralize": "^8.0.0",
|
||||
"prismjs": "1.30.0",
|
||||
@@ -432,8 +434,7 @@
|
||||
"resolutions": {
|
||||
"underscore": "1.13.7",
|
||||
"@types/slate": "0.47.11",
|
||||
"semver@~7.0.0": "7.5.4",
|
||||
"semver@7.3.4": "7.5.4",
|
||||
"semver@npm:~7.3.5": "^7.3.5",
|
||||
"debug@npm:^0.7.2": "2.6.9",
|
||||
"debug@npm:^0.7.4": "2.6.9",
|
||||
"slate-dev-environment@^0.2.2": "patch:slate-dev-environment@npm:0.2.5#.yarn/patches/slate-dev-environment-npm-0.2.5-9aeb7da7b5.patch",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"name": "@grafana/alerting",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana Alerting Library – Build vertical integrations on top of the industry-leading alerting solution",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
|
||||
@@ -10,10 +10,12 @@ export default [
|
||||
input: entryPoint,
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-alerting')],
|
||||
treeshake: false,
|
||||
},
|
||||
{
|
||||
input: 'src/unstable.ts',
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-alerting')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
+2
@@ -14,6 +14,8 @@ const meta: Meta<typeof ContactPointSelector> = {
|
||||
docs: {
|
||||
page: mdx,
|
||||
},
|
||||
// TODO fix a11y issue in story and remove this
|
||||
a11y: { test: 'off' },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"name": "@grafana/data",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana Data Library",
|
||||
"keywords": [
|
||||
"typescript"
|
||||
@@ -56,8 +56,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "7.0.1",
|
||||
"@grafana/i18n": "12.1.0-pre",
|
||||
"@grafana/schema": "12.1.0-pre",
|
||||
"@grafana/i18n": "12.2.0-pre",
|
||||
"@grafana/schema": "12.2.0-pre",
|
||||
"@leeoniya/ufuzzy": "1.0.18",
|
||||
"@types/d3-interpolate": "^3.0.0",
|
||||
"@types/string-hash": "1.1.3",
|
||||
@@ -73,7 +73,7 @@
|
||||
"marked-mangle": "1.1.11",
|
||||
"moment": "2.30.1",
|
||||
"moment-timezone": "0.5.47",
|
||||
"ol": "10.6.0",
|
||||
"ol": "10.6.1",
|
||||
"papaparse": "5.5.3",
|
||||
"react-use": "17.6.0",
|
||||
"rxjs": "7.8.2",
|
||||
|
||||
@@ -10,10 +10,12 @@ export default [
|
||||
input: entryPoint,
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-data')],
|
||||
treeshake: false,
|
||||
},
|
||||
{
|
||||
input: 'src/unstable.ts',
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-data')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -388,6 +388,59 @@ describe('sorted DataFrame', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('sorted DataFrame by nanos', () => {
|
||||
it('Should sort nanos with numeric timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{ name: 'first', type: FieldType.time, values: [1, 1, 2, 2, 3, 3], nanos: [100, 102, 1, 2, 1000, 999] },
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'c', 'd', 'e', 'f'] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 0, true);
|
||||
expect(sorted.length).toEqual(6);
|
||||
expect(sorted.fields[0].values).toEqual([3, 3, 2, 2, 1, 1]);
|
||||
expect(sorted.fields[1].values).toEqual(['e', 'f', 'd', 'c', 'b', 'a']);
|
||||
});
|
||||
|
||||
it('Should sort by nanos with dateTime timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{
|
||||
name: 'first',
|
||||
type: FieldType.time,
|
||||
values: [dateTime(50), dateTime(50), dateTime(100)],
|
||||
nanos: [1, 0, 100],
|
||||
},
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'c'] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 0);
|
||||
expect(sorted.length).toEqual(3);
|
||||
expect(sorted.fields[0].values).toEqual([dateTime(50), dateTime(50), dateTime(100)]);
|
||||
expect(sorted.fields[1].values).toEqual(['b', 'a', 'c']);
|
||||
});
|
||||
|
||||
// Not sure if we expect nanos to exist on any field type besides time fields, but the schema allows it.
|
||||
// Keep in mind if sorting by a non time field, the nanos is expected to present on the field that is being sorted
|
||||
it('Should sort by nanos with string timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{ name: 'fist', type: FieldType.time, values: [1, 2, 3, 3] },
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'b', 'c'], nanos: [100, 0, 1, 0] },
|
||||
{ name: 'third', type: FieldType.number, values: [2000, 3000, 1000] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 1, true);
|
||||
expect(sorted.length).toEqual(4);
|
||||
expect(sorted.fields[0].values).toEqual([3, 2, 3, 1]);
|
||||
expect(sorted.fields[0].nanos).toBeUndefined();
|
||||
expect(sorted.fields[1].values).toEqual(['c', 'b', 'b', 'a']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse DataFrame', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
|
||||
@@ -1,5 +1,90 @@
|
||||
import { initRegionalFormatForTests } from '@grafana/i18n';
|
||||
|
||||
import * as featureToggles from '../utils/featureToggles';
|
||||
|
||||
import { dateTimeFormat, dateTimeFormatTimeAgo, dateTimeFormatWithAbbrevation, timeZoneAbbrevation } from './formatter';
|
||||
|
||||
// Default time zone ("browser") is set to Pacific/Easter in jest.config.js
|
||||
const referenceDate = '2020-04-17T12:36:15.779Z';
|
||||
|
||||
describe('dateTimeFormat (regionalFormatPreference)', () => {
|
||||
let mockGetFeatureToggle: jest.SpyInstance;
|
||||
|
||||
beforeAll(() => {
|
||||
initRegionalFormatForTests('en-AU');
|
||||
mockGetFeatureToggle = jest.spyOn(featureToggles, 'getFeatureToggle').mockImplementation((featureName) => {
|
||||
return featureName === 'localeFormatPreference';
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
mockGetFeatureToggle.mockRestore();
|
||||
});
|
||||
|
||||
it('formats dates in the browsers timezone by default', () => {
|
||||
expect(dateTimeFormat(referenceDate)).toBe('17/04/2020, 6:36:15 am');
|
||||
});
|
||||
|
||||
it('formats dates in the browsers timezone by default when invalid time zone is set', () => {
|
||||
const options = { timeZone: 'asdf123' };
|
||||
expect(dateTimeFormat(referenceDate, options)).toBe('17/04/2020, 6:36:15 am');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['UTC', '17/04/2020, 12:36:15 pm'],
|
||||
['Europe/Stockholm', '17/04/2020, 2:36:15 pm'],
|
||||
['Australia/Perth', '17/04/2020, 8:36:15 pm'],
|
||||
['Asia/Yakutsk', '17/04/2020, 9:36:15 pm'],
|
||||
['America/Panama', '17/04/2020, 7:36:15 am'],
|
||||
['America/Los_Angeles', '17/04/2020, 5:36:15 am'],
|
||||
['Africa/Djibouti', '17/04/2020, 3:36:15 pm'],
|
||||
['Europe/London', '17/04/2020, 1:36:15 pm'],
|
||||
['Europe/Berlin', '17/04/2020, 2:36:15 pm'],
|
||||
['Europe/Moscow', '17/04/2020, 3:36:15 pm'],
|
||||
['Europe/Madrid', '17/04/2020, 2:36:15 pm'],
|
||||
['America/New_York', '17/04/2020, 8:36:15 am'],
|
||||
['America/Chicago', '17/04/2020, 7:36:15 am'],
|
||||
['America/Denver', '17/04/2020, 6:36:15 am'],
|
||||
])('formats with the supplied time zone %s', (timeZone, expected) => {
|
||||
expect(dateTimeFormat(referenceDate, { timeZone })).toBe(expected);
|
||||
});
|
||||
|
||||
it('does not include seconds in the output if the time does not', () => {
|
||||
expect(dateTimeFormat('2020-04-17T12:36:00.000Z')).toBe('17/04/2020, 6:36 am');
|
||||
});
|
||||
|
||||
it("includes milliseconds in the output when 'defaultWithMS' is set to true", () => {
|
||||
expect(dateTimeFormat('2020-04-17T12:36:15.123Z', { defaultWithMS: true })).toBe('17/04/2020, 6:36:15.123 am');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['en-GB', '17/04/2020, 06:36:15'],
|
||||
['en-US', '4/17/2020, 6:36:15 AM'],
|
||||
['fr-FR', '17/04/2020 06:36:15'],
|
||||
['es-ES', '17/4/2020, 6:36:15'],
|
||||
['de-DE', '17.4.2020, 06:36:15'],
|
||||
['pt-BR', '17/04/2020, 06:36:15'],
|
||||
['zh-Hans', '2020/4/17 06:36:15'],
|
||||
['it-IT', '17/04/2020, 06:36:15'],
|
||||
['ja-JP', '2020/4/17 6:36:15'],
|
||||
['id-ID', '17/4/2020, 06.36.15'],
|
||||
['ko-KR', '2020. 4. 17. 오전 6:36:15'],
|
||||
['ru-RU', '17.04.2020, 06:36:15'],
|
||||
['cs-CZ', '17. 4. 2020 6:36:15'],
|
||||
['nl-NL', '17-4-2020, 06:36:15'],
|
||||
['hu-HU', '2020. 04. 17. 6:36:15'],
|
||||
['pt-PT', '17/04/2020, 06:36:15'],
|
||||
['pl-PL', '17.04.2020, 06:36:15'],
|
||||
['sv-SE', '2020-04-17 06:36:15'],
|
||||
['tr-TR', '17.04.2020 06:36:15'],
|
||||
['zh-Hant', '2020/4/17 上午6:36:15'],
|
||||
])('with locale %s', (locale, expected) => {
|
||||
initRegionalFormatForTests(locale);
|
||||
|
||||
expect(dateTimeFormat(referenceDate)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateTimeFormat', () => {
|
||||
describe('when no time zone have been set', () => {
|
||||
const browserTime = dateTimeFormat(1587126975779, { timeZone: 'browser' });
|
||||
@@ -81,7 +166,7 @@ describe('dateTimeFormat', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DateTimeFormatISO', () => {
|
||||
describe('with custom ISO format', () => {
|
||||
it('should format according to ISO standard', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm', format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' };
|
||||
expect(dateTimeFormat(1587126975779, options)).toBe('2020-04-17T14:36:15.779+02:00');
|
||||
@@ -95,39 +180,41 @@ describe('dateTimeFormat', () => {
|
||||
expect(dateTimeFormat(1587126975779, options)).toBe('2020-04-17T14:36:15.779+02:00');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateTimeFormatTimeAgo', () => {
|
||||
it('should return the correct format for years ago', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(dateTimeFormatTimeAgo(1587126975779, options)).toContain('years ago');
|
||||
});
|
||||
describe('dateTimeFormatTimeAgo', () => {
|
||||
it('should return the correct format for years ago', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(dateTimeFormatTimeAgo(1587126975779, options)).toContain('years ago');
|
||||
});
|
||||
describe('dateTimeFormatWithAbbreviation', () => {
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 14:36:15 CEST');
|
||||
});
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'America/New_York' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 08:36:15 EDT');
|
||||
});
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Bucharest' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 15:36:15 EEST');
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateTimeFormatWithAbbreviation', () => {
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 14:36:15 CEST');
|
||||
});
|
||||
describe('timeZoneAbbrevation', () => {
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('CEST');
|
||||
});
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'America/New_York' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('EDT');
|
||||
});
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Bucharest' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('EEST');
|
||||
});
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'America/New_York' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 08:36:15 EDT');
|
||||
});
|
||||
it('should return the correct format with zone abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Bucharest' };
|
||||
expect(dateTimeFormatWithAbbrevation(1587126975779, options)).toBe('2020-04-17 15:36:15 EEST');
|
||||
});
|
||||
});
|
||||
|
||||
describe('timeZoneAbbrevation', () => {
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Stockholm' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('CEST');
|
||||
});
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'America/New_York' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('EDT');
|
||||
});
|
||||
it('should return the correct abbreviation', () => {
|
||||
const options = { timeZone: 'Europe/Bucharest' };
|
||||
expect(timeZoneAbbrevation(1587126975779, options)).toBe('EEST');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,77 @@
|
||||
/* eslint-disable id-blacklist, no-restricted-imports */
|
||||
import moment, { Moment } from 'moment-timezone';
|
||||
|
||||
import { formatDate } from '@grafana/i18n';
|
||||
|
||||
import { TimeZone } from '../types/time';
|
||||
import { getFeatureToggle } from '../utils/featureToggles';
|
||||
|
||||
import { DateTimeOptions, getTimeZone } from './common';
|
||||
import { systemDateFormats } from './formats';
|
||||
import { DateTimeInput, toUtc, dateTimeAsMoment } from './moment_wrapper';
|
||||
|
||||
/**
|
||||
* Converts a Grafana DateTimeInput to a plain Javascript Date object.
|
||||
*/
|
||||
function toDate(dateInUtc: DateTimeInput): Date {
|
||||
if (dateInUtc instanceof Date) {
|
||||
return dateInUtc;
|
||||
}
|
||||
|
||||
if (typeof dateInUtc === 'string' || typeof dateInUtc === 'number') {
|
||||
return new Date(dateInUtc);
|
||||
}
|
||||
|
||||
return dateTimeAsMoment(dateInUtc).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Grafana timezone string to an IANA timezone string.
|
||||
*/
|
||||
export function toIANATimezone(grafanaTimezone: string) {
|
||||
// Intl APIs will use the browser's timezone by default (if tz is undefined)
|
||||
if (grafanaTimezone === 'browser') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const zone = moment.tz.zone(grafanaTimezone);
|
||||
if (!zone) {
|
||||
// If the timezone is invalid, we default to the browser's timezone
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return grafanaTimezone;
|
||||
}
|
||||
|
||||
function getIntlOptions(
|
||||
date: Date,
|
||||
options?: DateTimeOptionsWithFormat
|
||||
): Intl.DateTimeFormatOptions & { timeZone?: string } {
|
||||
const timeZone = getTimeZone(options);
|
||||
|
||||
const intlOptions: Intl.DateTimeFormatOptions = {
|
||||
year: 'numeric', // ↔ dateStyle: 'short'
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: 'numeric', // ↔ timeStyle: 'short'
|
||||
minute: 'numeric',
|
||||
timeZone: toIANATimezone(timeZone),
|
||||
};
|
||||
|
||||
// If the time has seconds, ensure they're included in the format
|
||||
const hasSeconds = date.getSeconds() !== 0;
|
||||
if (hasSeconds) {
|
||||
intlOptions.second = 'numeric';
|
||||
}
|
||||
|
||||
if (options?.defaultWithMS) {
|
||||
intlOptions.second = 'numeric';
|
||||
intlOptions.fractionalSecondDigits = 3; // Include milliseconds
|
||||
}
|
||||
|
||||
return intlOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type describing the options that can be passed to the {@link dateTimeFormat}
|
||||
* helper function to control how the date and time value passed to the function is
|
||||
@@ -23,17 +88,30 @@ export interface DateTimeOptionsWithFormat extends DateTimeOptions {
|
||||
|
||||
type DateTimeFormatter<T extends DateTimeOptions = DateTimeOptions> = (dateInUtc: DateTimeInput, options?: T) => string;
|
||||
|
||||
// NOTE:
|
||||
// These date formatting functions now just wrap the @grafana/i18n formatting functions
|
||||
// (which themselves wrap the browserIntl APIs). In the future we may deprecate these
|
||||
// in favor of using @grafana/i18n directly.
|
||||
|
||||
/**
|
||||
* Helper function to format date and time according to the specified options. If no options
|
||||
* are supplied, then default values are used. For more details, see {@link DateTimeOptionsWithFormat}.
|
||||
* Helper function to format date and time according to the specified options.
|
||||
* If no options are supplied, then the date is formatting according to the user's locale preference.
|
||||
*
|
||||
* @param dateInUtc - date in UTC format, e.g. string formatted with UTC offset, UNIX epoch in seconds etc.
|
||||
* @param options
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const dateTimeFormat: DateTimeFormatter<DateTimeOptionsWithFormat> = (dateInUtc, options?) =>
|
||||
toTz(dateInUtc, getTimeZone(options)).format(getFormat(options));
|
||||
export const dateTimeFormat: DateTimeFormatter<DateTimeOptionsWithFormat> = (dateInUtc, options?) => {
|
||||
// If a custom format is provided (or the toggle isn't enabled), use the previous implementation
|
||||
if (!getFeatureToggle('localeFormatPreference') || options?.format) {
|
||||
return toTz(dateInUtc, getTimeZone(options)).format(getFormat(options));
|
||||
}
|
||||
|
||||
const dateAsDate = toDate(dateInUtc);
|
||||
const intlOptions = getIntlOptions(dateAsDate, options); // TODO - if invalid timezone, use browser timezone
|
||||
return formatDate(dateAsDate, intlOptions);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to format date and time according to the standard ISO format e.g. 2013-02-04T22:44:30.652Z.
|
||||
@@ -70,8 +148,18 @@ export const dateTimeFormatTimeAgo: DateTimeFormatter = (dateInUtc, options?) =>
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const dateTimeFormatWithAbbrevation: DateTimeFormatter = (dateInUtc, options?) =>
|
||||
toTz(dateInUtc, getTimeZone(options)).format(`${systemDateFormats.fullDate} z`);
|
||||
export const dateTimeFormatWithAbbrevation: DateTimeFormatter = (dateInUtc, options?) => {
|
||||
// If a custom format is provided (or the toggle isn't enabled), use the previous implementation
|
||||
if (!getFeatureToggle('localeFormatPreference') || options?.format) {
|
||||
return toTz(dateInUtc, getTimeZone(options)).format(`${systemDateFormats.fullDate} z`);
|
||||
}
|
||||
|
||||
const dateAsDate = toDate(dateInUtc);
|
||||
const intlOptions = getIntlOptions(dateAsDate, options);
|
||||
intlOptions.timeZoneName = 'short';
|
||||
|
||||
return formatDate(dateAsDate, intlOptions);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to return only the time zone abbreviation for a given date and time value. If no options
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { initRegionalFormatForTests } from '@grafana/i18n';
|
||||
|
||||
import { RawTimeRange, TimeRange } from '../types/time';
|
||||
import * as featureToggles from '../utils/featureToggles';
|
||||
|
||||
import { dateTime } from './moment_wrapper';
|
||||
import {
|
||||
convertRawToRange,
|
||||
describeInterval,
|
||||
describeTimeRange,
|
||||
isRelativeTimeRange,
|
||||
relativeToTimeRange,
|
||||
roundInterval,
|
||||
@@ -310,4 +314,180 @@ describe('Range Utils', () => {
|
||||
expect(relativeTimeRange.to).toEqual(604800);
|
||||
});
|
||||
});
|
||||
|
||||
describe('describeTimeRange', () => {
|
||||
it.each([
|
||||
['now-5m', 'now', 'Last 5 minutes'],
|
||||
['now-15m', 'now', 'Last 15 minutes'],
|
||||
['now-1h', 'now', 'Last 1 hour'],
|
||||
['now-24h', 'now', 'Last 24 hours'],
|
||||
['now-7d', 'now', 'Last 7 days'],
|
||||
['now-30d', 'now', 'Last 30 days'],
|
||||
['now/d', 'now/d', 'Today'],
|
||||
['now/d', 'now', 'Today so far'],
|
||||
['now/w', 'now/w', 'This week'],
|
||||
['now/M', 'now/M', 'This month'],
|
||||
['now/y', 'now/y', 'This year'],
|
||||
['now-1d/d', 'now-1d/d', 'Yesterday'],
|
||||
['now-1w/w', 'now-1w/w', 'Previous week'],
|
||||
['now-1M/M', 'now-1M/M', 'Previous month'],
|
||||
['now-1y/y', 'now-1y/y', 'Previous year'],
|
||||
['now/fQ', 'now/fQ', 'This fiscal quarter'],
|
||||
['now/fy', 'now/fy', 'This fiscal year'],
|
||||
['now-1Q/fQ', 'now-1Q/fQ', 'Previous fiscal quarter'],
|
||||
['now-1y/fy', 'now-1y/fy', 'Previous fiscal year'],
|
||||
])('should return display name "%s" for range from "%s" to "%s"', (from, to, expected) => {
|
||||
expect(describeTimeRange({ from, to })).toBe(expected);
|
||||
});
|
||||
|
||||
it('should prioritize custom quick ranges over standard ranges', () => {
|
||||
const customRanges = [{ from: 'now-5m', to: 'now', display: 'Lightning round!' }];
|
||||
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, customRanges)).toBe('Lightning round!');
|
||||
});
|
||||
|
||||
it('should format with the default timezone', () => {
|
||||
// Tests default to Pacific/Easter
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('2023-01-15 05:30:00 to 2023-01-15 09:45:00');
|
||||
});
|
||||
|
||||
it('should respect timezone in datetime formatting', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to }, 'Australia/Sydney');
|
||||
expect(result).toBe('2023-01-15 21:30:00 to 2023-01-16 01:45:00');
|
||||
});
|
||||
|
||||
it('should handle absolute from, relative to', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = 'now';
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('2023-01-15 05:30:00 to a few seconds ago');
|
||||
});
|
||||
|
||||
it('should handle relative from, absolute to', () => {
|
||||
const from = 'now-1h';
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('an hour ago to 2023-01-15 09:45:00');
|
||||
});
|
||||
|
||||
it('should handle invalid relative expressions', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = 'invalid-expression';
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toContain('Invalid date');
|
||||
});
|
||||
|
||||
it('should handle empty custom ranges array', () => {
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, [])).toBe('Last 5 minutes');
|
||||
});
|
||||
|
||||
it('should handle null custom ranges', () => {
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, undefined)).toBe('Last 5 minutes');
|
||||
});
|
||||
});
|
||||
|
||||
describe('describeTimeRange - localeFormatPreference enabled', () => {
|
||||
let mockGetFeatureToggle: jest.SpyInstance;
|
||||
|
||||
beforeAll(() => {
|
||||
initRegionalFormatForTests('en-AU');
|
||||
mockGetFeatureToggle = jest.spyOn(featureToggles, 'getFeatureToggle').mockImplementation((featureName) => {
|
||||
return featureName === 'localeFormatPreference';
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
mockGetFeatureToggle.mockRestore();
|
||||
});
|
||||
|
||||
it.each([
|
||||
['now-5m', 'now', 'Last 5 minutes'],
|
||||
['now-15m', 'now', 'Last 15 minutes'],
|
||||
['now-1h', 'now', 'Last 1 hour'],
|
||||
['now-7d', 'now', 'Last 7 days'],
|
||||
['now/d', 'now/d', 'Today'],
|
||||
['now/d', 'now', 'Today so far'],
|
||||
['now/w', 'now/w', 'This week'],
|
||||
['now-1d/d', 'now-1d/d', 'Yesterday'],
|
||||
['now-1w/w', 'now-1w/w', 'Previous week'],
|
||||
['now-1y/y', 'now-1y/y', 'Previous year'],
|
||||
['now/fQ', 'now/fQ', 'This fiscal quarter'],
|
||||
['now-1Q/fQ', 'now-1Q/fQ', 'Previous fiscal quarter'],
|
||||
])('should return display name "%s" for range from "%s" to "%s"', (from, to, expected) => {
|
||||
expect(describeTimeRange({ from, to })).toBe(expected);
|
||||
});
|
||||
|
||||
it('should prioritize custom quick ranges over standard ranges', () => {
|
||||
const customRanges = [{ from: 'now-5m', to: 'now', display: 'Lightning round!' }];
|
||||
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, customRanges)).toBe('Lightning round!');
|
||||
});
|
||||
|
||||
it('should format with the default timezone', () => {
|
||||
// Tests default to Pacific/Easter
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('15/1/23, 5:30 – 9:45 am');
|
||||
});
|
||||
|
||||
it('should respect timezone in datetime formatting', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to }, 'Australia/Sydney');
|
||||
expect(result).toBe('15/1/23, 9:30 pm – 16/1/23, 1:45 am');
|
||||
});
|
||||
|
||||
it('should include seconds in the output if the time has seconds', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = dateTime('2023-01-15T14:45:12Z');
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('15/1/23, 5:30:00 am – 9:45:12 am');
|
||||
});
|
||||
|
||||
it('should handle absolute from, relative to', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = 'now';
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('15/01/2023, 5:30 am to a few seconds ago');
|
||||
});
|
||||
|
||||
it('should handle relative from, absolute to', () => {
|
||||
const from = 'now-1h';
|
||||
const to = dateTime('2023-01-15T14:45:00Z');
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toBe('an hour ago to 15/01/2023, 9:45 am');
|
||||
});
|
||||
|
||||
it('should handle invalid relative expressions', () => {
|
||||
const from = dateTime('2023-01-15T10:30:00Z');
|
||||
const to = 'invalid-expression';
|
||||
|
||||
const result = describeTimeRange({ from, to });
|
||||
expect(result).toContain('Invalid date');
|
||||
});
|
||||
|
||||
it('should handle empty custom ranges array', () => {
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, [])).toBe('Last 5 minutes');
|
||||
});
|
||||
|
||||
it('should handle null custom ranges', () => {
|
||||
expect(describeTimeRange({ from: 'now-5m', to: 'now' }, undefined, undefined)).toBe('Last 5 minutes');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { formatDateRange } from '@grafana/i18n';
|
||||
|
||||
import { RawTimeRange, TimeRange, TimeZone, IntervalValues, RelativeTimeRange, TimeOption } from '../types/time';
|
||||
import { getFeatureToggle } from '../utils/featureToggles';
|
||||
|
||||
import * as dateMath from './datemath';
|
||||
import { timeZoneAbbrevation, dateTimeFormat, dateTimeFormatTimeAgo } from './formatter';
|
||||
import { timeZoneAbbrevation, dateTimeFormat, dateTimeFormatTimeAgo, toIANATimezone } from './formatter';
|
||||
import { isDateTime, DateTime, dateTime } from './moment_wrapper';
|
||||
import { dateTimeParse } from './parser';
|
||||
|
||||
@@ -134,6 +137,17 @@ export function describeTextRange(expr: string): TimeOption {
|
||||
return opt;
|
||||
}
|
||||
|
||||
// TODO: Should we keep these format presets somewhere common?
|
||||
const rangeFormatShort: Intl.DateTimeFormatOptions = {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'short',
|
||||
};
|
||||
|
||||
const rangeFormatFull: Intl.DateTimeFormatOptions = {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'medium',
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this function to get a properly formatted string representation of a {@link @grafana/data:RawTimeRange | range}.
|
||||
*
|
||||
@@ -154,9 +168,25 @@ export function describeTimeRange(range: RawTimeRange, timeZone?: TimeZone, quic
|
||||
const options = { timeZone };
|
||||
|
||||
if (isDateTime(range.from) && isDateTime(range.to)) {
|
||||
return dateTimeFormat(range.from, options) + ' to ' + dateTimeFormat(range.to, options);
|
||||
const fromDate = range.from.toDate();
|
||||
const toDate = range.to.toDate();
|
||||
|
||||
if (!getFeatureToggle('localeFormatPreference')) {
|
||||
return dateTimeFormat(range.from, options) + ' to ' + dateTimeFormat(range.to, options);
|
||||
}
|
||||
|
||||
const hasSeconds = fromDate.getSeconds() !== 0 || toDate.getSeconds() !== 0;
|
||||
const intlFormat = hasSeconds ? rangeFormatFull : rangeFormatShort;
|
||||
const intlFormatOptions = {
|
||||
...intlFormat,
|
||||
timeZone: timeZone ? toIANATimezone(timeZone) : undefined,
|
||||
};
|
||||
|
||||
return formatDateRange(fromDate, toDate, intlFormatOptions);
|
||||
}
|
||||
|
||||
// TODO: We could update these to all use Intl APIs.
|
||||
// Could we use formatRangeToParts and replace the 'other side' with the ago formatting?
|
||||
if (isDateTime(range.from)) {
|
||||
const parsed = dateMath.parse(range.to, true, 'utc');
|
||||
return parsed ? dateTimeFormat(range.from, options) + ' to ' + dateTimeFormatTimeAgo(parsed, options) : '';
|
||||
|
||||
@@ -17,9 +17,9 @@ export const fieldIndexComparer = (field: Field, reverse = false): IndexComparer
|
||||
return booleanIndexComparer(values, reverse);
|
||||
case FieldType.time:
|
||||
if (typeof field.values[0] === 'number') {
|
||||
return timestampIndexComparer(values, reverse);
|
||||
return timestampIndexComparer(values, reverse, field.nanos);
|
||||
}
|
||||
return timeIndexComparer(values, reverse);
|
||||
return timeIndexComparer(values, reverse, field.nanos);
|
||||
default:
|
||||
return naturalIndexComparer(reverse);
|
||||
}
|
||||
@@ -79,17 +79,24 @@ const falsyComparer = (a: unknown, b: unknown): number => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
const timestampIndexComparer = (values: number[], reverse: boolean): IndexComparer => {
|
||||
const timestampIndexComparer = (values: number[], reverse: boolean, nanos?: number[]): IndexComparer => {
|
||||
let mult = reverse ? -1 : 1;
|
||||
|
||||
if (nanos !== undefined) {
|
||||
return (a: number, b: number): number => mult * (values[a] - values[b] || nanos[a] - nanos[b]);
|
||||
}
|
||||
|
||||
return (a: number, b: number): number => mult * (values[a] - values[b]);
|
||||
};
|
||||
|
||||
const timeIndexComparer = (values: unknown[], reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? timeComparer(vB, vA) : timeComparer(vA, vB);
|
||||
};
|
||||
const timeIndexComparer = (values: unknown[], reverse: boolean, nanos?: number[]): IndexComparer => {
|
||||
const mult = reverse ? -1 : 1;
|
||||
|
||||
if (nanos !== undefined) {
|
||||
return (a: number, b: number): number => mult * (timeComparer(values[a], values[b]) || nanos[a] - nanos[b]);
|
||||
}
|
||||
|
||||
return (a: number, b: number): number => mult * timeComparer(values[a], values[b]);
|
||||
};
|
||||
|
||||
const booleanIndexComparer = (values: boolean[], reverse: boolean): IndexComparer => {
|
||||
|
||||
@@ -166,11 +166,6 @@ export interface FeatureToggles {
|
||||
*/
|
||||
pluginsFrontendSandbox?: boolean;
|
||||
/**
|
||||
* Enables right panel for the plugins details page
|
||||
* @default true
|
||||
*/
|
||||
pluginsDetailsRightPanel?: boolean;
|
||||
/**
|
||||
* Enables previous SQL data source dataset dropdown behavior
|
||||
*/
|
||||
sqlDatasourceDatabaseSelection?: boolean;
|
||||
@@ -353,6 +348,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
alertmanagerRemoteSecondary?: boolean;
|
||||
/**
|
||||
* Enables a feature to avoid issues with concurrent writes to the alerting provenance table in MySQL
|
||||
*/
|
||||
alertingProvenanceLockWrites?: boolean;
|
||||
/**
|
||||
* Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager.
|
||||
*/
|
||||
alertmanagerRemotePrimary?: boolean;
|
||||
@@ -397,6 +396,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
canvasPanelPanZoom?: boolean;
|
||||
/**
|
||||
* Enables time comparison option in supported panels
|
||||
*/
|
||||
timeComparison?: boolean;
|
||||
/**
|
||||
* Enables infinite scrolling for the Logs panel in Explore and Dashboards
|
||||
* @default true
|
||||
*/
|
||||
@@ -473,6 +476,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
sqlExpressions?: boolean;
|
||||
/**
|
||||
* Enables column autocomplete for SQL Expressions
|
||||
*/
|
||||
sqlExpressionsColumnAutoComplete?: boolean;
|
||||
/**
|
||||
* Enables the group to nested table transformation
|
||||
* @default true
|
||||
*/
|
||||
@@ -748,6 +755,11 @@ export interface FeatureToggles {
|
||||
*/
|
||||
alertingAIGenAlertRules?: boolean;
|
||||
/**
|
||||
* Enable AI-generated feedback from the Grafana UI.
|
||||
* @default false
|
||||
*/
|
||||
alertingAIFeedback?: boolean;
|
||||
/**
|
||||
* Enable AI-improve alert rules labels and annotations.
|
||||
* @default false
|
||||
*/
|
||||
@@ -1054,4 +1066,8 @@ export interface FeatureToggles {
|
||||
* Enable dual reader for unified storage search
|
||||
*/
|
||||
unifiedStorageSearchDualReaderEnabled?: boolean;
|
||||
/**
|
||||
* Enables adhoc filtering support for the dashboard datasource
|
||||
*/
|
||||
dashboardDsAdHocFiltering?: boolean;
|
||||
}
|
||||
|
||||
@@ -274,6 +274,8 @@ export const availableIconsIndex = {
|
||||
attach: true,
|
||||
'dollar-alt': true,
|
||||
'ai-sparkle': true,
|
||||
bitbucket: true,
|
||||
git: true,
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof availableIconsIndex;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { FeatureToggles } from '../types/featureToggles.gen';
|
||||
|
||||
type FeatureToggleName = keyof FeatureToggles;
|
||||
|
||||
/**
|
||||
* Check a featureToggle
|
||||
* @param featureName featureToggle name
|
||||
* @param def default value if featureToggles aren't defined, false if not provided
|
||||
* @returns featureToggle value or def.
|
||||
*/
|
||||
export function getFeatureToggle(featureName: FeatureToggleName, def = false) {
|
||||
return window.grafanaBootData?.settings.featureToggles[featureName] ?? def;
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @deprecated
|
||||
* This is defined on the theme object now. Use `theme.visualization.palette` instead.
|
||||
*/
|
||||
export const classicColors = [
|
||||
'#7EB26D', // 0: pale green
|
||||
'#EAB839', // 1: mustard
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"name": "@grafana/e2e-selectors",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana End-to-End Test Selectors Library",
|
||||
"keywords": [
|
||||
"cli",
|
||||
|
||||
@@ -10,5 +10,6 @@ export default [
|
||||
input: entryPoint,
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-e2e-selectors')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@grafana/eslint-plugin",
|
||||
"description": "ESLint rules for use within the Grafana repo. Not suitable (or supported) for external use.",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"main": "./index.cjs",
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/types": "^8.9.0",
|
||||
"eslint": "9.28.0",
|
||||
"eslint": "9.31.0",
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
"private": true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"name": "@grafana/flamegraph",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana flamegraph visualization component",
|
||||
"keywords": [
|
||||
"grafana",
|
||||
@@ -44,8 +44,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@emotion/css": "11.13.5",
|
||||
"@grafana/data": "12.1.0-pre",
|
||||
"@grafana/ui": "12.1.0-pre",
|
||||
"@grafana/data": "12.2.0-pre",
|
||||
"@grafana/ui": "12.2.0-pre",
|
||||
"@leeoniya/ufuzzy": "1.0.18",
|
||||
"d3": "^7.8.5",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -10,5 +10,6 @@ export default [
|
||||
input: entryPoint,
|
||||
plugins,
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-flamegraph')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"name": "@grafana/i18n",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana Internationalization Library",
|
||||
"keywords": [
|
||||
"grafana",
|
||||
|
||||
@@ -16,5 +16,6 @@ export default [
|
||||
}),
|
||||
],
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-i18n')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import memoize from 'micro-memoize';
|
||||
import memoize, { AnyFn, Memoized } from 'micro-memoize';
|
||||
|
||||
const deepMemoize: typeof memoize = (fn) => memoize(fn, { isEqual: deepEqual });
|
||||
|
||||
function clearMemoizedCache(fn: Memoized<AnyFn>) {
|
||||
fn.cache.keys.length = 0;
|
||||
fn.cache.values.length = 0;
|
||||
}
|
||||
|
||||
let regionalFormat: string | undefined;
|
||||
|
||||
const createDateTimeFormatter = deepMemoize((locale: string | undefined, options: Intl.DateTimeFormatOptions) => {
|
||||
@@ -41,5 +46,10 @@ export const formatDateRange = (
|
||||
};
|
||||
|
||||
export const initRegionalFormat = (regionalFormatArg: string) => {
|
||||
// We don't expect this to be called with a different locale during the lifetime of the app,
|
||||
// so this is mostly here so we can change it during tests and clear out previously memoized values.
|
||||
clearMemoizedCache(formatDate);
|
||||
clearMemoizedCache(formatDuration);
|
||||
|
||||
regionalFormat = regionalFormatArg;
|
||||
};
|
||||
|
||||
@@ -24,4 +24,4 @@ export {
|
||||
} from './constants';
|
||||
export { initPluginTranslations, t, Trans } from './i18n';
|
||||
export type { ResourceLoader, Resources, TFunction, TransProps } from './types';
|
||||
export { formatDate, formatDuration, formatDateRange } from './dates';
|
||||
export { formatDate, formatDuration, formatDateRange, initRegionalFormat as initRegionalFormatForTests } from './dates';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"license": "AGPL-3.0-only",
|
||||
"name": "@grafana/o11y-ds-frontend",
|
||||
"private": true,
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Library to manage traces in Grafana.",
|
||||
"sideEffects": false,
|
||||
"repository": {
|
||||
@@ -18,12 +18,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/css": "11.13.5",
|
||||
"@grafana/data": "12.1.0-pre",
|
||||
"@grafana/e2e-selectors": "12.1.0-pre",
|
||||
"@grafana/data": "12.2.0-pre",
|
||||
"@grafana/e2e-selectors": "12.2.0-pre",
|
||||
"@grafana/plugin-ui": "0.10.7",
|
||||
"@grafana/runtime": "12.1.0-pre",
|
||||
"@grafana/schema": "12.1.0-pre",
|
||||
"@grafana/ui": "12.1.0-pre",
|
||||
"@grafana/runtime": "12.2.0-pre",
|
||||
"@grafana/schema": "12.2.0-pre",
|
||||
"@grafana/ui": "12.2.0-pre",
|
||||
"react-select": "5.10.2",
|
||||
"react-use": "17.6.0",
|
||||
"rxjs": "7.8.2",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@grafana/plugin-configs",
|
||||
"description": "Shared dependencies and files for core plugins",
|
||||
"private": true,
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"dependencies": {
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
@@ -15,9 +15,9 @@
|
||||
"@types/eslint": "9.6.1",
|
||||
"@types/webpack-bundle-analyzer": "^4.7.0",
|
||||
"copy-webpack-plugin": "12.0.2",
|
||||
"eslint": "9.28.0",
|
||||
"eslint": "9.31.0",
|
||||
"eslint-webpack-plugin": "4.2.0",
|
||||
"fork-ts-checker-webpack-plugin": "9.0.2",
|
||||
"fork-ts-checker-webpack-plugin": "9.1.0",
|
||||
"glob": "11.0.3",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"imports-loader": "^5.0.0",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Grafana Labs",
|
||||
"license": "AGPL-3.0-only",
|
||||
"name": "@grafana/prometheus",
|
||||
"version": "12.1.0-pre",
|
||||
"version": "12.2.0-pre",
|
||||
"description": "Grafana Prometheus Library",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
@@ -41,13 +41,13 @@
|
||||
"dependencies": {
|
||||
"@emotion/css": "11.13.5",
|
||||
"@floating-ui/react": "0.27.13",
|
||||
"@grafana/data": "12.1.0-pre",
|
||||
"@grafana/e2e-selectors": "12.1.0-pre",
|
||||
"@grafana/i18n": "12.1.0-pre",
|
||||
"@grafana/data": "12.2.0-pre",
|
||||
"@grafana/e2e-selectors": "12.2.0-pre",
|
||||
"@grafana/i18n": "12.2.0-pre",
|
||||
"@grafana/plugin-ui": "0.10.7",
|
||||
"@grafana/runtime": "12.1.0-pre",
|
||||
"@grafana/schema": "12.1.0-pre",
|
||||
"@grafana/ui": "12.1.0-pre",
|
||||
"@grafana/runtime": "12.2.0-pre",
|
||||
"@grafana/schema": "12.2.0-pre",
|
||||
"@grafana/ui": "12.2.0-pre",
|
||||
"@hello-pangea/dnd": "18.0.1",
|
||||
"@leeoniya/ufuzzy": "1.0.18",
|
||||
"@lezer/common": "1.2.3",
|
||||
|
||||
@@ -13,5 +13,6 @@ export default [
|
||||
input: entryPoint,
|
||||
plugins: [...plugins, image(), json(), dynamicImportVars()],
|
||||
output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-prometheus')],
|
||||
treeshake: false,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -21,7 +21,7 @@ import { PromVisualQuery } from './querybuilder/types';
|
||||
* @param operator
|
||||
*/
|
||||
export function addLabelToQuery(query: string, key: string, value: string | number, operator = '='): string {
|
||||
if (!key || !value) {
|
||||
if (!key) {
|
||||
throw new Error('Need label to add to query.');
|
||||
}
|
||||
|
||||
|
||||
@@ -515,19 +515,6 @@ export default class PromQlLanguageProvider extends LanguageProvider implements
|
||||
};
|
||||
}
|
||||
|
||||
export interface PrometheusLanguageProviderInterface
|
||||
extends PrometheusBaseLanguageProvider,
|
||||
PrometheusLegacyLanguageProvider {
|
||||
retrieveMetricsMetadata: () => PromMetricsMetadata;
|
||||
retrieveHistogramMetrics: () => string[];
|
||||
retrieveMetrics: () => string[];
|
||||
retrieveLabelKeys: () => string[];
|
||||
|
||||
queryMetricsMetadata: (limit?: number) => Promise<PromMetricsMetadata>;
|
||||
queryLabelKeys: (timeRange: TimeRange, match?: string, limit?: number) => Promise<string[]>;
|
||||
queryLabelValues: (timeRange: TimeRange, labelKey: string, match?: string, limit?: number) => Promise<string[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modern implementation of the Prometheus language provider that abstracts API endpoint selection.
|
||||
*
|
||||
@@ -535,12 +522,73 @@ export interface PrometheusLanguageProviderInterface
|
||||
* - Automatically selects the most efficient API endpoint based on Prometheus version and configuration
|
||||
* - Supports both labels and series endpoints for backward compatibility
|
||||
* - Handles match[] parameters for filtering time series data
|
||||
* - Implements automatic request limiting (default: 40_000 series)
|
||||
* - Implements automatic request limiting (default: 40,000 series if not configured otherwise)
|
||||
* - Provides unified interface for both modern and legacy Prometheus versions
|
||||
* - Provides caching mechanism based on time range, limit, and match parameters
|
||||
*
|
||||
* @see LabelsApiClient For modern Prometheus versions using the labels API
|
||||
* @see SeriesApiClient For legacy Prometheus versions using the series API
|
||||
*/
|
||||
export interface PrometheusLanguageProviderInterface
|
||||
extends PrometheusBaseLanguageProvider,
|
||||
PrometheusLegacyLanguageProvider {
|
||||
/**
|
||||
* Initializes the language provider by fetching metrics, label keys, and metrics metadata using Resource Clients.
|
||||
* All calls use the limit parameter from datasource configuration (default: 40,000 if not set).
|
||||
*
|
||||
* For backward compatibility, it calls _backwardCompatibleStart.
|
||||
* Some places still rely on deprecated fields. Until we replace them, we need _backwardCompatibleStart method.
|
||||
*/
|
||||
start: (timeRange?: TimeRange) => Promise<any[]>;
|
||||
|
||||
/**
|
||||
* Returns already cached metrics metadata including type and help information.
|
||||
* If there is no cached metadata, it returns an empty object.
|
||||
* To get fresh metadata, use queryMetricsMetadata instead.
|
||||
*/
|
||||
retrieveMetricsMetadata: () => PromMetricsMetadata;
|
||||
|
||||
/**
|
||||
* Returns already cached list of histogram metrics (identified by '_bucket' suffix).
|
||||
* If there are no cached histogram metrics, it returns an empty array.
|
||||
*/
|
||||
retrieveHistogramMetrics: () => string[];
|
||||
|
||||
/**
|
||||
* Returns already cached list of all available metric names.
|
||||
* If there are no cached metrics, it returns an empty array.
|
||||
*/
|
||||
retrieveMetrics: () => string[];
|
||||
|
||||
/**
|
||||
* Returns already cached list of available label keys.
|
||||
* If there are no cached label keys, it returns an empty array.
|
||||
*/
|
||||
retrieveLabelKeys: () => string[];
|
||||
|
||||
/**
|
||||
* Fetches fresh metrics metadata from Prometheus with optional limit.
|
||||
* Uses datasource's default limit if not specified.
|
||||
*/
|
||||
queryMetricsMetadata: (limit?: number) => Promise<PromMetricsMetadata>;
|
||||
|
||||
/**
|
||||
* Queries Prometheus for label keys within time range, optionally filtered by match selector.
|
||||
* Automatically selects labels or series endpoint based on datasource configuration.
|
||||
* If no limit is provided, uses the datasource's default limit configuration.
|
||||
* Use zero (0) to fetch all label keys, but this might return huge amounts of data.
|
||||
*/
|
||||
queryLabelKeys: (timeRange: TimeRange, match?: string, limit?: number) => Promise<string[]>;
|
||||
|
||||
/**
|
||||
* Queries Prometheus for values of a specific label key, optionally filtered by match selector.
|
||||
* Automatically selects labels or series endpoint based on datasource configuration.
|
||||
* If no limit is provided, uses the datasource's default limit configuration.
|
||||
* Use zero (0) to fetch all label values, but this might return huge amounts of data.
|
||||
*/
|
||||
queryLabelValues: (timeRange: TimeRange, labelKey: string, match?: string, limit?: number) => Promise<string[]>;
|
||||
}
|
||||
|
||||
export class PrometheusLanguageProvider extends PromQlLanguageProvider implements PrometheusLanguageProviderInterface {
|
||||
private _metricsMetadata?: PromMetricsMetadata;
|
||||
private _resourceClient?: ResourceApiClient;
|
||||
|
||||
@@ -191,6 +191,18 @@ describe('expandRecordingRules()', () => {
|
||||
const result = expandRecordingRules(query, mapping);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it('when there is an empty label value it should still be able to expand the rule', () => {
|
||||
const query = `sum(max by (cluster, container) (pod_cpu:active:kube_limits{container!="", cluster=~"pink"}))`;
|
||||
const mapping = {
|
||||
'pod_cpu:active:kube_limits': {
|
||||
expandedQuery: `kube_limits{job!="", resource="cpu"} * on (namespace, pod, cluster) group_left () max by (namespace, pod, cluster) ((kube_pod_status_phase{phase=~"Pending|Running"} == 1))`,
|
||||
},
|
||||
};
|
||||
const expected = `sum(max by (cluster, container) (kube_limits{job!="", resource="cpu", container!="", cluster=~"pink"} * on (namespace, pod, cluster) group_left () max by (namespace, pod, cluster) ((kube_pod_status_phase{phase=~"Pending|Running", container!="", cluster=~"pink"} == 1))))`;
|
||||
const result = expandRecordingRules(query, mapping);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('escapeLabelValueInExactSelector()', () => {
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Filtrovat názvy metrik podle vyhledávání regulárních výrazů pomocí dalšího volání rozhraní Prometheus API.",
|
||||
@@ -321,6 +418,13 @@
|
||||
"title-add": "Přidat {{name}}",
|
||||
"title-remove": "Odebrat {{name}}"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Nastavit dolní limit pro parametr kroku",
|
||||
"aria-label-select-resolution": "Vyberte rozlišení",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Filtern Sie Metriknamen per Regex-Suche und nutzen Sie dabei einen zusätzlichen Aufruf der Prometheus-API.",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "{{name}} hinzufügen",
|
||||
"title-remove": "{{name}} entfernen"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Untergrenze für den Schrittparameter festlegen",
|
||||
"aria-label-select-resolution": "Auflösung auswählen",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Filtrez les noms de métriques par recherche d’expression régulière, en utilisant un appel supplémentaire sur l’API Prometheus.",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "Ajouter {{name}}",
|
||||
"title-remove": "Supprimer {{name}}"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Définir la limite inférieure pour le paramètre d’étape",
|
||||
"aria-label-select-resolution": "Sélectionner une résolution",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "A metrikanevek szűrése reguláris kifejezéses kereséssel, a Prometheus API további hívásával.",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "{{name}} hozzáadása",
|
||||
"title-remove": "{{name}} eltávolítása"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Állítsa be a léptékparaméter alsó határát",
|
||||
"aria-label-select-resolution": "Felbontás kiválasztása",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Filter nama metrik dengan pencarian regex, menggunakan panggilan tambahan pada API Prometheus.",
|
||||
@@ -318,6 +415,13 @@
|
||||
"title-add": "Tambahkan {{name}}",
|
||||
"title-remove": "Hapus {{name}}"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Tetapkan batas bawah untuk parameter langkah",
|
||||
"aria-label-select-resolution": "Pilih resolusi",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Prometheus APIの追加呼び出しを使用して、正規表現検索でメトリック名をフィルタリングします。",
|
||||
@@ -318,6 +415,13 @@
|
||||
"title-add": "{{name}}を追加",
|
||||
"title-remove": "{{name}}を削除"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "ステップパラメーターの下限を設定",
|
||||
"aria-label-select-resolution": "解像度を選択",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -318,6 +415,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "Filter metrische namen op regex-zoekopdracht, met behulp van een extra oproep op de Prometheus-API.",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "{{name}} toevoegen",
|
||||
"title-remove": "{{name}} verwijderen"
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "Ondergrens instellen voor de stapparameter",
|
||||
"aria-label-select-resolution": "Resolutie selecteren",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -321,6 +418,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -321,6 +418,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
@@ -209,6 +209,103 @@
|
||||
"label-verbose": ""
|
||||
}
|
||||
},
|
||||
"promql": {
|
||||
"getAggregationOptions": {
|
||||
"documentation-avg": "",
|
||||
"documentation-bottomk": "",
|
||||
"documentation-count": "",
|
||||
"documentation-count-values": "",
|
||||
"documentation-group": "",
|
||||
"documentation-max": "",
|
||||
"documentation-min": "",
|
||||
"documentation-quantile": "",
|
||||
"documentation-stddev": "",
|
||||
"documentation-stdvar": "",
|
||||
"documentation-sum": "",
|
||||
"documentation-topk": ""
|
||||
},
|
||||
"getFunctions": {
|
||||
"documentation-abs": "",
|
||||
"documentation-absent": "",
|
||||
"documentation-absent-over-time": "",
|
||||
"documentation-avg-over-time": "",
|
||||
"documentation-ceil": "",
|
||||
"documentation-changes": "",
|
||||
"documentation-clamp": "",
|
||||
"documentation-clamp-max": "",
|
||||
"documentation-clamp-min": "",
|
||||
"documentation-count-over-time": "",
|
||||
"documentation-count-scalar": "",
|
||||
"documentation-day-of-month": "",
|
||||
"documentation-day-of-week": "",
|
||||
"documentation-day-of-year": "",
|
||||
"documentation-days-in-month": "",
|
||||
"documentation-deg": "",
|
||||
"documentation-delta": "",
|
||||
"documentation-deriv": "",
|
||||
"documentation-double-exponential-smoothing": "",
|
||||
"documentation-drop-common-labels": "",
|
||||
"documentation-exp": "",
|
||||
"documentation-floor": "",
|
||||
"documentation-histogram-avg": "",
|
||||
"documentation-histogram-count": "",
|
||||
"documentation-histogram-fraction": "",
|
||||
"documentation-histogram-quantile": "",
|
||||
"documentation-histogram-stddev": "",
|
||||
"documentation-histogram-stdvar": "",
|
||||
"documentation-histogram-sum": "",
|
||||
"documentation-holt-winters": "",
|
||||
"documentation-hour": "",
|
||||
"documentation-idelta": "",
|
||||
"documentation-increase": "",
|
||||
"documentation-info": "",
|
||||
"documentation-irate": "",
|
||||
"documentation-label-join": "",
|
||||
"documentation-label-replace": "",
|
||||
"documentation-last-over-time": "",
|
||||
"documentation-ln": "",
|
||||
"documentation-log10": "",
|
||||
"documentation-log2": "",
|
||||
"documentation-max-over-time": "",
|
||||
"documentation-min-over-time": "",
|
||||
"documentation-minute": "",
|
||||
"documentation-month": "",
|
||||
"documentation-pi": "",
|
||||
"documentation-predict-linear": "",
|
||||
"documentation-present-over-time": "",
|
||||
"documentation-quantile-over-time": "",
|
||||
"documentation-rad": "",
|
||||
"documentation-rate": "",
|
||||
"documentation-resets": "",
|
||||
"documentation-round": "",
|
||||
"documentation-scalar": "",
|
||||
"documentation-sgn": "",
|
||||
"documentation-sort": "",
|
||||
"documentation-sort-desc": "",
|
||||
"documentation-sqrt": "",
|
||||
"documentation-stddev-over-time": "",
|
||||
"documentation-stdvar-over-time": "",
|
||||
"documentation-sum-over-time": "",
|
||||
"documentation-time": "",
|
||||
"documentation-timestamp": "",
|
||||
"documentation-vector": "",
|
||||
"documentation-year": ""
|
||||
},
|
||||
"getTrigonometricFunctions": {
|
||||
"documentation-acos": "",
|
||||
"documentation-acosh": "",
|
||||
"documentation-asin": "",
|
||||
"documentation-asinh": "",
|
||||
"documentation-atan": "",
|
||||
"documentation-atanh": "",
|
||||
"documentation-cos": "",
|
||||
"documentation-cosh": "",
|
||||
"documentation-sin": "",
|
||||
"documentation-sinh": "",
|
||||
"documentation-tan": "",
|
||||
"documentation-tanh": ""
|
||||
}
|
||||
},
|
||||
"querybuilder": {
|
||||
"additional-settings": {
|
||||
"content-filter-metric-names-regex-search-using": "",
|
||||
@@ -319,6 +416,13 @@
|
||||
"title-add": "",
|
||||
"title-remove": ""
|
||||
},
|
||||
"operation-utils": {
|
||||
"getAggregationExplainer": {
|
||||
"label-by": "",
|
||||
"label-default": "",
|
||||
"label-without": ""
|
||||
}
|
||||
},
|
||||
"prom-query-builder-options": {
|
||||
"aria-label-lower-limit-parameter": "",
|
||||
"aria-label-select-resolution": "",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user