Merge branch 'main' into renovate/reduxjs-toolkit-1.x

This commit is contained in:
Ashley Harrison
2022-11-24 14:07:16 +00:00
784 changed files with 25873 additions and 23490 deletions
+28 -343
View File
@@ -1538,7 +1538,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/Table/utils.test.ts:5381": [
"packages/grafana-ui/src/components/Table/utils.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
@@ -1548,19 +1548,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Unexpected any. Specify a different type.", "19"]
[0, 0, 0, "Unexpected any. Specify a different type.", "9"]
],
"packages/grafana-ui/src/components/Table/utils.ts:5381": [
"packages/grafana-ui/src/components/Table/utils.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
@@ -3995,12 +3985,6 @@ exports[`better eslint`] = {
"public/app/features/folders/state/actions.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/geo/editor/GazetteerPathEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/features/geo/format/geohash.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -4554,6 +4538,9 @@ exports[`better eslint`] = {
"public/app/features/sandbox/TestStuffPage.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/scenes/components/layout/SceneFlexLayout.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -4651,8 +4638,7 @@ exports[`better eslint`] = {
"public/app/features/search/state/SearchStateManager.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"]
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/features/search/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -6349,8 +6335,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -6649,16 +6634,8 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/OperationHeader.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/OperationParamEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -6670,22 +6647,13 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/plugins/datasource/prometheus/querybuilder/state.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/prometheus/querybuilder/state.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/prometheus/result_transformer.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -6721,8 +6689,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "31"]
],
"public/app/plugins/datasource/prometheus/result_transformer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/prometheus/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@@ -6732,8 +6699,7 @@ exports[`better eslint`] = {
],
"public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -6767,16 +6733,15 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Do not use any type assertions.", "8"],
[0, 0, 0, "Do not use any type assertions.", "9"],
[0, 0, 0, "Do not use any type assertions.", "10"],
[0, 0, 0, "Do not use any type assertions.", "11"],
[0, 0, 0, "Do not use any type assertions.", "12"],
[0, 0, 0, "Do not use any type assertions.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"]
[0, 0, 0, "Unexpected any. Specify a different type.", "16"]
],
"public/app/plugins/datasource/tempo/language_provider.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -6810,33 +6775,7 @@ exports[`better eslint`] = {
],
"public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"]
],
"public/app/plugins/datasource/tempo/traceql/autocomplete.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/testdata/ConfigEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -6850,13 +6789,10 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Do not use any type assertions.", "7"],
[0, 0, 0, "Do not use any type assertions.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Do not use any type assertions.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"]
[0, 0, 0, "Unexpected any. Specify a different type.", "8"]
],
"public/app/plugins/datasource/testdata/components/PredictablePulseEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@@ -6876,13 +6812,11 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/plugins/datasource/testdata/components/SimulationSchemaForm.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/testdata/components/StreamingClientEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@@ -6998,18 +6932,14 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/panel/barchart/TickSpacingEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/barchart/bars.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Do not use any type assertions.", "7"]
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Do not use any type assertions.", "6"]
],
"public/app/plugins/panel/barchart/module.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -7018,29 +6948,10 @@ exports[`better eslint`] = {
"public/app/plugins/panel/barchart/quadtree.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/barchart/suggestions.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/panel/barchart/utils.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"]
],
"public/app/plugins/panel/barchart/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/bargauge/BarGaugePanel.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/candlestick/CandlestickPanel.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -7067,9 +6978,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "10"],
[0, 0, 0, "Do not use any type assertions.", "11"]
],
"public/app/plugins/panel/canvas/CanvasContextMenu.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/canvas/CanvasPanel.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
@@ -7113,8 +7021,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"public/app/plugins/panel/canvas/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/dashlist/module.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -7131,12 +7038,6 @@ exports[`better eslint`] = {
"public/app/plugins/panel/debug/RenderInfoViewer.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/flamegraph/components/FlameGraphHeader.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/gauge/GaugeMigrations.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/gauge/GaugeMigrations.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -7154,16 +7055,12 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/plugins/panel/geomap/editor/FrameSelectionEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/panel/geomap/editor/GeomapStyleRulesEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/panel/geomap/editor/StyleEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
@@ -7174,8 +7071,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "8"],
[0, 0, 0, "Do not use any type assertions.", "9"],
[0, 0, 0, "Do not use any type assertions.", "10"],
[0, 0, 0, "Do not use any type assertions.", "11"],
[0, 0, 0, "Do not use any type assertions.", "12"]
[0, 0, 0, "Do not use any type assertions.", "11"]
],
"public/app/plugins/panel/geomap/editor/StyleRuleEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@@ -7201,9 +7097,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/plugins/panel/geomap/style/utils.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/geomap/utils/layers.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
@@ -7215,14 +7108,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/panel/geomap/view.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/plugins/panel/gettingstarted/GettingStarted.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/gettingstarted/components/Step.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7568,191 +7453,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/plugins/panel/graph/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/panel/heatmap-old/axes_editor.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"]
],
"public/app/plugins/panel/heatmap-old/color_legend.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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, "Do not use any type assertions.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Do not use any type assertions.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Do not use any type assertions.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Do not use any type assertions.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Do not use any type assertions.", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
[0, 0, 0, "Unexpected any. Specify a different type.", "22"]
],
"public/app/plugins/panel/heatmap-old/color_scale.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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"]
],
"public/app/plugins/panel/heatmap-old/display_editor.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/plugins/panel/heatmap-old/heatmap_ctrl.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"]
],
"public/app/plugins/panel/heatmap-old/heatmap_data_converter.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"]
],
"public/app/plugins/panel/heatmap-old/heatmap_tooltip.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
[0, 0, 0, "Unexpected any. Specify a different type.", "24"],
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
[0, 0, 0, "Unexpected any. Specify a different type.", "26"],
[0, 0, 0, "Unexpected any. Specify a different type.", "27"],
[0, 0, 0, "Unexpected any. Specify a different type.", "28"]
],
"public/app/plugins/panel/heatmap-old/rendering.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
[0, 0, 0, "Unexpected any. Specify a different type.", "24"],
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
[0, 0, 0, "Unexpected any. Specify a different type.", "26"],
[0, 0, 0, "Unexpected any. Specify a different type.", "27"],
[0, 0, 0, "Unexpected any. Specify a different type.", "28"],
[0, 0, 0, "Unexpected any. Specify a different type.", "29"],
[0, 0, 0, "Unexpected any. Specify a different type.", "30"],
[0, 0, 0, "Unexpected any. Specify a different type.", "31"],
[0, 0, 0, "Unexpected any. Specify a different type.", "32"],
[0, 0, 0, "Unexpected any. Specify a different type.", "33"],
[0, 0, 0, "Unexpected any. Specify a different type.", "34"],
[0, 0, 0, "Unexpected any. Specify a different type.", "35"],
[0, 0, 0, "Unexpected any. Specify a different type.", "36"],
[0, 0, 0, "Unexpected any. Specify a different type.", "37"],
[0, 0, 0, "Unexpected any. Specify a different type.", "38"],
[0, 0, 0, "Unexpected any. Specify a different type.", "39"],
[0, 0, 0, "Unexpected any. Specify a different type.", "40"],
[0, 0, 0, "Unexpected any. Specify a different type.", "41"],
[0, 0, 0, "Unexpected any. Specify a different type.", "42"],
[0, 0, 0, "Unexpected any. Specify a different type.", "43"],
[0, 0, 0, "Do not use any type assertions.", "44"],
[0, 0, 0, "Unexpected any. Specify a different type.", "45"],
[0, 0, 0, "Unexpected any. Specify a different type.", "46"]
],
"public/app/plugins/panel/heatmap-old/specs/heatmap_ctrl.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/plugins/panel/heatmap-old/specs/heatmap_data_converter.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/plugins/panel/heatmap-old/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[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"]
],
"public/app/plugins/panel/heatmap/HeatmapHoverView.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -7847,31 +7547,19 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/nodeGraph/Edge.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/nodeGraph/EdgeLabel.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/nodeGraph/Legend.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/plugins/panel/nodeGraph/Legend.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/nodeGraph/Node.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/nodeGraph/NodeGraph.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"]
[0, 0, 0, "Do not use any type assertions.", "3"]
],
"public/app/plugins/panel/nodeGraph/ViewControls.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -8185,9 +7873,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
[0, 0, 0, "Unexpected any. Specify a different type.", "16"]
],
"public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
+4 -5
View File
@@ -2,9 +2,8 @@
init_cmds = [
["make", "gen-go"],
["make", "gen-jsonnet"],
["GO_BUILD_DEV=1", "make", "build-cli"],
["GO_BUILD_DEV=1", "make", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
["GO_BUILD_DEV=1", "make", "build-go"],
["./bin/grafana", "server", "-packaging=dev", "cfg:app_mode=development"]
]
watch_all = true
follow_symlinks = true
@@ -20,6 +19,6 @@ build_delay = 1500
cmds = [
["make", "gen-go"],
["make", "gen-jsonnet"],
["GO_BUILD_DEV=1", "make", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
["GO_BUILD_DEV=1", "make", "build-go"],
["./bin/grafana", "server", "-packaging=dev", "cfg:app_mode=development"]
]
+3 -2
View File
@@ -7,7 +7,7 @@
load('scripts/drone/events/pr.star', 'pr_pipelines')
load('scripts/drone/events/main.star', 'main_pipelines')
load('scripts/drone/pipelines/docs.star', 'docs_pipelines')
load('scripts/drone/events/release.star', 'release_pipelines', 'publish_artifacts_pipelines', 'publish_npm_pipelines', 'publish_packages_pipeline', 'artifacts_page_pipeline')
load('scripts/drone/events/release.star', 'oss_pipelines', 'enterprise_pipelines', 'enterprise2_pipelines', 'publish_artifacts_pipelines', 'publish_npm_pipelines', 'publish_packages_pipeline', 'artifacts_page_pipeline')
load('scripts/drone/pipelines/publish_images.star', 'publish_image_pipelines_public', 'publish_image_pipelines_security')
load('scripts/drone/version.star', 'version_branch_pipelines')
load('scripts/drone/events/cron.star', 'cronjobs')
@@ -15,7 +15,8 @@ load('scripts/drone/vault.star', 'secrets')
def main(ctx):
edition = 'oss'
return pr_pipelines(edition=edition) + main_pipelines(edition=edition) + release_pipelines() + \
return pr_pipelines(edition=edition) + main_pipelines(edition=edition) + oss_pipelines() + enterprise_pipelines() + enterprise2_pipelines() + \
enterprise2_pipelines(prefix='custom-', trigger = {'event': ['custom']},) + \
publish_image_pipelines_public() + publish_image_pipelines_security() + \
publish_artifacts_pipelines('security') + publish_artifacts_pipelines('public') + \
publish_npm_pipelines('public') + publish_packages_pipeline() + artifacts_page_pipeline() + \
+833 -39
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -114,6 +114,8 @@ go.sum @grafana/backend-platform
/contribute/architecture/backend @grafana/backend-platform
/contribute/engineering/backend @grafana/backend-platform
package.json @grafana/frontend-ops
tsconfig.json @grafana/frontend-ops
/crowdin.yml @grafana/user-essentials
/public/locales @grafana/user-essentials
/public/app/core/internationalization @grafana/user-essentials
@@ -167,8 +169,6 @@ go.sum @grafana/backend-platform
/scripts/grunt @grafana/frontend-ops
/scripts/webpack @grafana/frontend-ops
/scripts/generate-a11y-report.sh @grafana/user-essentials
package.json @grafana/frontend-ops
tsconfig.json @grafana/frontend-ops
lerna.json @grafana/frontend-ops
.babelrc @grafana/frontend-ops
.prettierrc.js @grafana/frontend-ops
@@ -205,6 +205,7 @@ lerna.json @grafana/frontend-ops
/grafana-mixin/ @grafana/hosted-grafana-team
# Grafana authentication and authorization
/pkg/login @grafana/grafana-authnz-team
/pkg/services/accesscontrol @grafana/grafana-authnz-team
/pkg/services/auth @grafana/grafana-authnz-team
/pkg/services/dashboards/accesscontrol.go @grafana/grafana-authnz-team
@@ -217,6 +218,7 @@ lerna.json @grafana/frontend-ops
/pkg/services/oauthtoken @grafana/grafana-authnz-team
/pkg/services/teamguardian @grafana/grafana-authnz-team
/pkg/services/serviceaccounts @grafana/grafana-authnz-team
/pkg/services/loginattempt @grafana/grafana-authnz-team
# Grafana Partnerships Team
/pkg/infra/httpclient/httpclientprovider/sigv4_middleware.go @grafana/grafana-partnerships-team
+1
View File
@@ -105,6 +105,7 @@ debug.test
/packaging/**/*.tar.gz
/packaging/**/*.tar.gz.sha256
pkg/cmd/grafana-server/__debug_bin
pkg/services/quota/quotaimpl/storage/storage.json
# Ignore OSX indexing
.DS_Store
+2 -2
View File
@@ -6,10 +6,10 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/pkg/cmd/grafana-server/",
"program": "${workspaceFolder}/pkg/cmd/grafana/",
"env": {},
"cwd": "${workspaceFolder}",
"args": ["--homepath", "${workspaceFolder}", "--packaging", "dev"]
"args": ["server", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
},
{
"name": "Attach to Chrome",
Binary file not shown.
Binary file not shown.
+18
View File
@@ -167,6 +167,24 @@ The following functions and classes related to logs are deprecated in the `grafa
- **Toolkit:** Deprecate `component:create` command. [#56086](https://github.com/grafana/grafana/pull/56086), [@academo](https://github.com/academo)
- **Toolkit:** Remove changelog command. [#56073](https://github.com/grafana/grafana/pull/56073), [@gitstart](https://github.com/gitstart)
<!-- 9.2.6 START -->
# 9.2.6 (2022-11-22)
### Features and enhancements
- **Alerting:** Support Prometheus durations in Provisioning API. [#58293](https://github.com/grafana/grafana/pull/58293), [@bartpeeters](https://github.com/bartpeeters)
- **SSE:** Keep value name from numeric table. [#58831](https://github.com/grafana/grafana/pull/58831), [@kylebrandt](https://github.com/kylebrandt)
- **Transformations:** Make Card Descriptions Clickable. [#58717](https://github.com/grafana/grafana/pull/58717), [@zuchka](https://github.com/zuchka)
### Bug fixes
- **MS/My/PostgresSQL:** Migrate annotation query. [#58847](https://github.com/grafana/grafana/pull/58847), [@zoltanbedi](https://github.com/zoltanbedi)
- **Search:** Fixes issue with Recent/Starred section always displaying "General" folder. [#58746](https://github.com/grafana/grafana/pull/58746), [@JoaoSilvaGrafana](https://github.com/JoaoSilvaGrafana)
- **Server:** Write internal server error on missing write. [#57813](https://github.com/grafana/grafana/pull/57813), [@sakjur](https://github.com/sakjur)
<!-- 9.2.6 END -->
<!-- 9.2.5 START -->
# 9.2.5 (2022-11-16)
+1 -1
View File
@@ -82,7 +82,7 @@ RUN export GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
COPY --from=go-builder /grafana/bin/*/grafana-server /grafana/bin/*/grafana-cli ./bin/
COPY --from=go-builder /grafana/bin/*/grafana-server /grafana/bin/*/grafana-cli /grafana/bin/*/grafana ./bin/
COPY --from=js-builder /grafana/public ./public
COPY --from=js-builder /grafana/tools ./tools
+1 -1
View File
@@ -77,7 +77,7 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
COPY --from=go-builder /src/grafana/bin/*/grafana-server /src/grafana/bin/*/grafana-cli bin/
COPY --from=go-builder /src/grafana/bin/*/grafana-server /src/grafana/bin/*/grafana-cli /grafana/bin/*/grafana bin/
COPY --from=js-builder /usr/src/app/public public
COPY --from=js-builder /usr/src/app/tools tools
+5 -1
View File
@@ -7,7 +7,7 @@ WIRE_TAGS = "oss"
-include local/Makefile
include .bingo/Variables.mk
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-full build-docker-full-ubuntu lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help gen-go gen-cue
.PHONY: all deps-go deps-js deps build-go build-backend build-server build-cli build-js build build-docker-full build-docker-full-ubuntu lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help gen-go gen-cue
GO = go
GO_FILES ?= ./pkg/...
@@ -82,6 +82,10 @@ build-go: $(MERGED_SPEC_TARGET) gen-go ## Build all Go binaries.
@echo "build go files"
$(GO) run build.go $(GO_BUILD_FLAGS) build
build-backend: ## Build Grafana backend.
@echo "build backend"
$(GO) run build.go $(GO_BUILD_FLAGS) build-backend
build-server: ## Build Grafana server.
@echo "build server"
$(GO) run build.go $(GO_BUILD_FLAGS) build-server
+2 -3
View File
@@ -14,7 +14,6 @@ Grafana Labs will send you a response indicating the next steps in handling your
## Security announcements
We maintain a category on the community site called [Security Announcements](https://community.grafana.com/c/support/security-announcements),
where we will post a summary, remediation, and mitigation details for any patch containing security fixes.
We will post a summary, remediation, and mitigation details for any patch containing security fixes on the Grafana blog. The security announcement blog posts will be tagged with the [security tag](https://grafana.com/tags/security/).
You can also subscribe to email updates to this category if you have a grafana.com account and sign on to the community site or track updates via an [RSS feed](https://community.grafana.com/c/support/security-announcements.rss).
You can also track security announcements via the [RSS feed](https://grafana.com/tags/security/index.xml).
+8 -2
View File
@@ -412,8 +412,8 @@ password_hint = password
# Default UI theme ("dark" or "light")
default_theme = dark
# Default locale (supported IETF language tag, such as en-US)
default_locale = en-US
# Default UI language (supported IETF language tag, such as en-US)
default_language = en-US
# Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash.
home_page =
@@ -435,6 +435,10 @@ user_invite_max_lifetime_duration = 24h
# Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves.
hidden_users =
[service_accounts]
# When set, Grafana will not allow the creation of tokens with expiry greater than this setting.
token_expiration_day_limit =
[auth]
# Login cookie name
login_cookie_name = grafana_session
@@ -1268,6 +1272,8 @@ license_path =
# enable = feature1,feature2
enable =
internationalization = true
# feature1 = true
# feature2 = false
+7 -2
View File
@@ -412,8 +412,8 @@
# Default UI theme ("dark" or "light")
;default_theme = dark
# Default locale (supported IETF language tag, such as en-US)
;default_locale = en-US
# Default UI language (supported IETF language tag, such as en-US)
;default_language = en-US
# Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash.
;home_page =
@@ -435,6 +435,11 @@
# Enter a comma-separated list of users login to hide them in the Grafana UI. These users are shown to Grafana admins and themselves.
; hidden_users =
[service_accounts]
# Service account maximum expiration date in days.
# When set, Grafana will not allow the creation of tokens with expiry greater than this setting.
; token_expiration_day_limit =
[auth]
# Login cookie name
;login_cookie_name = grafana_session
+8
View File
@@ -135,6 +135,14 @@ Some examples when backport is not required:
- The change is supposed to be released in the next major/minor release, e.g. v8.0.0, but the release branch, e.g. v8.0.x, has not yet been created.
#### Required labels
To ensure that we don't backport pull requests that don't need to be backported, i.e. implement new features, and only backport pull requests that address bugs, have a product approval, or refer to docs changes, backport labels need to be followed by either:
- `type/bug` label: Pull requests which address bugs,
- `product-approved` label: Urgent fixes which need product approval, in order to get merged,
- `type/docs` label: Docs changes`.
> **Note:** You can still backport a pull request after it's been merged.
## Doing the actual merge
+16
View File
@@ -4,6 +4,7 @@ This folder contains useful scripts and configuration so you can:
- Configure data sources in Grafana for development.
- Configure dashboards for development and test scenarios.
- Set up an SMTP Server + Web Interface for viewing and testing emails.
- Create docker-compose file with databases and fake data.
## Install Docker
@@ -58,6 +59,21 @@ Jaeger block runs both Jaeger and Loki container. Loki container sends traces to
| 1.0 | graphite1 | 8280 | 2203 | 2203 |
| 0.9 | graphite09 | 8380 | 2303 | 2303 |
#### MailDev
MailDev block runs an SMTP server and a web UI to test and view emails. This is useful for testing your email notifications locally.
Make sure you configure your .ini file with the following settings:
```ini
[smtp]
enabled = true
skip_verify = true
host = "localhost:1025"
```
You can access the web UI at http://localhost:12080/#/
## Debugging setup in VS Code
An example of launch.json is provided in `devenv/vscode/launch.json`. It basically does what Makefile and .bra.toml do. The 'program' field is set to the folder name so VS Code loads all *.go files in it instead of just main.go.
@@ -1,5 +1,8 @@
loki:
image: grafana/loki:latest
command: -config.file=/etc/loki/loki-config.yaml
volumes:
- ./docker/blocks/loki/loki-config.yaml:/etc/loki/loki-config.yaml
ports:
- "3100:3100"
@@ -0,0 +1,44 @@
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://localhost:9093
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
#
# Statistics help us better understand how Loki is used, and they show us performance
# levels for most users. This helps us prioritize features and documentation.
# For more information on what's sent, look at
# https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go
# Refer to the buildReport method to see what goes into a report.
#
# If you would like to disable reporting, uncomment the following lines:
#analytics:
# reporting_enabled: false
@@ -27,9 +27,6 @@ Before you can create your first dashboard, you need to add your data source.
**To add a data source:**
1. Select the cog icon on the side menu to show the configuration options.
{{< figure src="/static/img/docs/v75/sidemenu-datasource-7-5.png" max-width="150px" class="docs-image--no-shadow">}}
1. Select **Data sources**.
This opens the data sources page, which displays a list of previously configured data sources for the Grafana instance.
@@ -44,9 +41,7 @@ Before you can create your first dashboard, you need to add your data source.
1. Move the cursor over the data source you want to add.
{{< figure src="/static/img/docs/v75/select-data-source-7-5.png" max-width="700px" class="docs-image--no-shadow">}}
1. Select **Select**.
1. Click **Select**.
This opens the data source configuration page.
@@ -63,8 +58,6 @@ Each data source's configuration includes a permissions page where you can enabl
### Enable data source permissions
{{< figure src="/static/img/docs/enterprise/datasource_permissions_enable_still.png" class="docs-image--no-shadow docs-image--right" max-width= "600px" animated-gif="/static/img/docs/enterprise/datasource_permissions_enable.gif" >}}
By default, data sources in an organization can be queried by any user in that organization. For example, a user with the `Viewer` role can issue any possible query to a data source, not just
queries that exist on dashboards they have access to.
@@ -82,8 +75,6 @@ When permissions are enabled for a data source in an organization, the user who
### Allow users and teams to query a data source
{{< figure src="/static/img/docs/enterprise/datasource_permissions_add_still.png" class="docs-image--no-shadow docs-image--right" max-width= "600px" animated-gif="/static/img/docs/enterprise/datasource_permissions_add.gif" >}}
After you have enabled permissions for a data source you can assign query permissions to users and teams which will allow access to query the data source.
**Assign query permission to users and teams:**
@@ -98,8 +89,6 @@ After you have enabled permissions for a data source you can assign query permis
### Disable data source permissions
{{< figure src="/static/img/docs/enterprise/datasource_permissions_disable_still.png" class="docs-image--no-shadow docs-image--right" max-width= "600px" animated-gif="/static/img/docs/enterprise/datasource_permissions_disable.gif" >}}
If you have enabled permissions for a data source and want to return data source permissions to the default, then you can disable permissions with a click of a button.
Note that _all_ existing permissions created for the data source will be deleted.
@@ -60,8 +60,6 @@ Complete this task when you want to view a list of existing organizations.
A list of organizations appears.
![Server Admin organization list](/static/img/docs/manage-users/server-org-list-7-3.png)
## Create an organization
Create an organization when you want to isolate dashboards and other resources from each other.
@@ -117,5 +115,3 @@ Edit an organization when you want to change its name.
1. Hover your cursor over the **Server Admin** (shield) icon until a menu appears, and click **Orgs**.
1. Click the organization you want to edit.
1. Update the organization name and click **Update**.
![Server admin Edit Organization](/static/img/docs/manage-users/server-admin-edit-org-7-3.png)
@@ -88,8 +88,6 @@ To browse for available plugins:
1. Click the **All** filter to browse all available plugins.
1. Click the **Data sources**, **Panels**, or **Applications** buttons to filter by plugin type.
![Plugin catalog browse](/static/img/docs/plugins/plugins-catalog-browse-9.2.png)
### Install a plugin
To install a plugin:
@@ -101,8 +99,6 @@ To install a plugin:
When the update is complete, you see a confirmation message that the installation was successful.
![Plugin catalog install](/static/img/docs/plugins/plugins-catalog-install-8-1.png)
### Update a plugin
To update a plugin:
@@ -113,8 +109,6 @@ To update a plugin:
When the update is complete, you see a confirmation message that the update was successful.
![Plugin catalog update](/static/img/docs/plugins/plugins-catalog-update-8-1.png)
### Uninstall a plugin
To uninstall a plugin:
@@ -125,8 +119,6 @@ To uninstall a plugin:
When the update is complete, you see a confirmation message that the uninstall was successful.
![Plugin catalog uninstall](/static/img/docs/plugins/plugins-catalog-uninstall-8-1.png)
## Install Grafana plugins
Grafana supports data source, panel, and app plugins. Having panels as plugins makes it easy to create and add any kind of panel, to show your data, or improve your favorite dashboards. Apps enable the bundling of data sources, panels, dashboards, and Grafana pages into a cohesive experience.
@@ -53,8 +53,6 @@ In both cases, the assignment applies only to the user, team or service account
4. In the **Role** column, select the fixed role that you want to assign to the user, team or service account.
5. Click **Update**.
![User role picker in an organization](/static/img/docs/enterprise/user_role_picker_in_org.png)
**To assign a fixed role as a server administrator:**
1. Sign in to Grafana, hover your cursor over **Server Admin** (the shield icon) in the left navigation menu, and click **Users**.
@@ -62,8 +60,6 @@ In both cases, the assignment applies only to the user, team or service account
1. In the **Organizations** section, select a role within an organization that you want to assign to the user.
1. Click **Update**.
![User role picker in Organization](/static/img/docs/enterprise/user_role_picker_global.png)
## Assign fixed or custom roles to a team using provisioning
Instead of using the Grafana role picker, you can use file-based provisioning to assign fixed roles to teams. If you have a large number of teams, provisioning can provide an easier approach to assigning and managing role assignments.
@@ -14,9 +14,10 @@ weight: 30
The table below describes all RBAC configuration options. Like any other Grafana configuration, you can apply these options as [environment variables]({{< relref "../../../../setup-grafana/configure-grafana/#configure-with-environment-variables" >}}).
| Setting | Required | Description | Default |
| ------------------ | -------- | ---------------------------------------------------------------------------- | ------- |
| `permission_cache` | No | Enable to use in memory cache for loading and evaluating users' permissions. | `true` |
| Setting | Required | Description | Default |
| ------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `permission_cache` | No | Enable to use in memory cache for loading and evaluating users' permissions. | `true` |
| `permission_validation_enabled` | No | Grafana enforces validation for permissions when a user creates or updates a role. The system checks the internal list of scopes and actions for each permission to determine they are valid. By default, if a scope or action is not recognized, Grafana logs a warning message. When set to `true`, Grafana returns an error. | `false` |
## Example RBAC configuration
@@ -89,6 +89,10 @@ You can create a service account token using the Grafana UI or via the API. For
- Ensure you have permission to create and edit service accounts. By default, the organization administrator role is required to create and edit service accounts. For more information about user permissions, refer to [About users and permissions]({{< relref "../roles-and-permissions/#" >}}).
### Service account token expiration dates
By default, service account tokens don't have an expiration date, meaning they won't expire at all. However, if `token_expiration_day_limit` is set to a value greater than 0, Grafana restricts the lifetime limit of new tokens to the configured value in days.
### To add a token to a service account
1. Sign in to Grafana, then hover your cursor over **Configuration** (the gear icon) in the sidebar.
@@ -62,8 +62,6 @@ To add a team member:
1. Choose if you want to add the user as a team Member or an Admin.
1. Click **Add to team**.
![Add team member](/static/img/docs/manage-users/add-team-member-7-3.png)
## Grant team member permissions
Complete this task when you want to add or modify team member permissions.
@@ -76,8 +74,6 @@ To grant team member permissions:
1. In the team member list, find and click the user that you want to change. You can use the search field to filter the list if necessary.
1. Click the **Permission** list, and then click the new user permission level.
![Change team member permissions](/static/img/docs/manage-users/change-team-permissions-7-3.png)
## Remove a team member
You can remove a team member when you no longer want to apply team permissions to the user
@@ -33,8 +33,6 @@ You can see a list of users with accounts in your Grafana organization. If neces
1. Sign in to Grafana as an organization administrator.
1. Hover your cursor over the **Configuration** (gear) icon in the side menu and click **Users**.
![Org Admin user list](/static/img/docs/manage-users/org-user-list-7-3.png)
> **Note:** If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also [view a global list of users]({{< relref "../server-user-management#view-a-list-of-users" >}}) in the Server Admin section of Grafana.
## Change a user's organization permissions
@@ -96,8 +94,6 @@ When you invite users to join an organization, you assign the **Admin**, **Edito
If the invitee is not already a user, the system adds them.
![Invite User](/static/img/docs/manage-users/org-invite-user-7-3.png).
## Manage a pending invitation
Periodically review invitations you have sent so that you can see a list of users that have not yet accepted the invitation or cancel a pending invitation.
@@ -116,14 +112,10 @@ Periodically review invitations you have sent so that you can see a list of user
The **Pending Invites** button appears only when there are unaccepted invitations.
![Pending Invites button](/static/img/docs/manage-users/pending-invites-button-7-3.png)
To cancel an invitation, click the red **X** next to the invitation.
To copy an invitation link and send it directly to a user, click Copy Invite. You can then paste the invite link into a message.
![Pending Invites list](/static/img/docs/manage-users/pending-invites-list-7-3.png)
## Remove a user from an organization
You can remove a user from an organization when they no longer require access to the dashboard or data sources owned by the organization. No longer requiring access to an organization might occur when the user has left your company or has internally moved to another organization.
@@ -38,8 +38,6 @@ You can see a list of users with accounts on your Grafana server. This action mi
1. Sign in to Grafana as a server administrator.
1. Hover your cursor over the **Server Admin** (shield) icon until a menu appears, and click **Users**.
![Server Admin user list](/static/img/docs/manage-users/server-user-list-7-3.png)
> **Note:** If you have [organization administrator]({{< relref "../../roles-and-permissions/#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can still [view of list of users in a given organization]({{< relref "../manage-org-users/#view-a-list-of-organization-users" >}}).
## View user details
@@ -62,26 +60,18 @@ A user account contains the following sections.
This section contains basic user information, which users can update.
![Server Admin user information section](/static/img/docs/manage-users/server-admin-user-information-7-3.png)
#### Permissions
This indicates whether the user account has the Grafana administrator flag applied. If the flag is set to **Yes**, then the user is a Grafana server administrator.
![Server Admin Permissions section](/static/img/docs/manage-users/server-admin-permissions-7-3.png)
#### Organizations
This section lists the organizations the user belongs to and their assigned role.
![Server Admin Organizations section](/static/img/docs/manage-users/server-admin-organisations-7-3.png)
#### Sessions
This section includes recent user sessions and information about the time the user logged in and they system they used. You can force logouts, if necessary.
![Server Admin Sessions section](/static/img/docs/manage-users/server-admin-sessions-7-3.png)
## Edit a user account
Edit a user account when you want to modify user login credentials, or delete, disable, or enable a user.
@@ -15,7 +15,7 @@ weight: 400
# Create a Grafana managed alerting rule
Grafana allows you to create alerting rules that query one or more data sources, reduce or transform the results and compare them to each other or to fix thresholds. When these are executed, Grafana sends notifications to the contact point. For information on Grafana Alerting, see [About Grafana Alerting]({{< relref "../" >}}) which explains the various components of Grafana Alerting. We also recommend that you familiarize yourself with some of the [fundamental concepts]({{< relref "../fundamentals/" >}}) of Grafana Alerting.
Grafana allows you to create alerting rules that query one or more data sources, reduce or transform the results and compare them to each other or to fixed thresholds. When these are executed, Grafana sends notifications to the contact point. For information on Grafana Alerting, see [About Grafana Alerting]({{< relref "../" >}}) which explains the various components of Grafana Alerting. We also recommend that you familiarize yourself with some of the [fundamental concepts]({{< relref "../fundamentals/" >}}) of Grafana Alerting.
Watch this video to learn more about creating alerts: {{< vimeo 720001934 >}}
@@ -23,26 +23,28 @@ Watch this video to learn more about creating alerts: {{< vimeo 720001934 >}}
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
1. Click **New alert rule**. The new alerting rule page opens where the Grafana managed alerts option is selected by default.
1. In Step 1, add queries and expressions to evaluate, and then select the alert condition.
1. In Step 1, add the rule name.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 2, add queries and expressions to evaluate, and then select the alert condition.
- For queries, select a data source from the drop-down.
- Add one or more [queries]({{< relref "../../panels-visualizations/query-transform-data/#add-a-query/" >}}) or [expressions]({{< relref "../../panels-visualizations/query-transform-data/expression-queries/" >}}).
- For each expression, select either **Classic condition** to create a single alert rule, or choose from **Math**, **Reduce**, **Resample** options to generate separate alert for each series. For details on these options, see [Single and multi dimensional rule](#single-and-multi-dimensional-rule).
- Click **Run queries** to verify that the query is successful.
- Next, select the query or expression for your alert condition.
1. In Step 2, specify the alert evaluation interval.
1. In Step 3, specify the alert evaluation interval.
- From the **Condition** drop-down, select the query or expression to trigger the alert rule.
- For **Evaluate every**, specify the frequency of evaluation. Must be a multiple of 10 seconds. For examples, `1m`, `30s`.
- For **Evaluate for**, specify the duration for which the condition must be true before an alert fires.
> **Note:** Once a condition is breached, the alert goes into the Pending state. If the condition remains breached for the duration specified, the alert transitions to the `Firing` state, otherwise it reverts back to the `Normal` state.
- In **Configure no data and error handling**, configure alerting behavior in the absence of data. Use the guidelines in [No data and error handling](#no-data-and-error-handling).
- Click **Preview alerts** to check the result of running the query at this moment. Preview excludes no data and error handling.
1. In Step 3, add the rule name, storage location, rule group, as well as additional metadata associated with the rule.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 4, add the storage location, rule group, as well as additional metadata associated with the rule.
- From the **Folder** drop-down, select the folder where you want to store the rule.
- For **Group**, specify a pre-defined group. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
- Add Runbook URL, panel, dashboard, and alert IDs.
- Add custom labels.
1. In Step 5, add custom labels.
- Add custom labels selecting existing key-value pairs from the drop down, or add new labels by entering the new key or value .
1. Click **Save** to save the rule or **Save and exit** to save the rule and go back to the Alerting page.
1. Next, create a for the rule.
@@ -37,11 +37,12 @@ To create a Grafana Mimir or Loki managed recording rule
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
1. Click **New alert rule**. The new alerting rule page opens where the **Grafana managed alert** option is selected by default.
1. In Step 1, select **Mimir or Loki recording rule** option.
1. In Step 1, add the rule name.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 2, select **Mimir or Loki recording rule** option.
- Select your Loki or Prometheus data source, add the query to evaluate, and then select the alert condition.
- Enter a PromQL or LogQL expression. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
1. In Step 2, add the rule name, namespace, rule group, as well as additional metadata associated with the rule.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 3, add the namespace, rule group, as well as additional metadata associated with the rule.
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click Add new and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose. For more information, see [Grafana Mimir or Loki rule groups and namespaces]({{< relref "edit-mimir-loki-namespace-group/" >}}).
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
@@ -52,18 +53,20 @@ To create a Grafana Mimir or Loki managed recording rule
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
1. Click **New alert rule**.
1. In Step 1, add the rule name, type, and storage location.
1. In Step 1, add the rule name.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 2, add the type, and storage location.
- From the **Rule type** drop-down, select **Mimir / Loki managed alert**.
- From the **Select data source** drop-down, select an external Prometheus, an external Loki, or a Grafana Cloud data source.
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose.
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
{{< figure src="/static/img/docs/alerting/unified/rule-edit-mimir-alert-type-8-0.png" max-width="550px" caption="Alert details" >}}
1. In Step 2, add the query to evaluate.
1. In Step 3, add the query to evaluate.
- Enter a PromQL or LogQL expression. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
{{< figure src="/static/img/docs/alerting/unified/rule-edit-mimir-query-8-0.png" max-width="550px" caption="Alert details" >}}
1. In Step 3, add additional metadata associated with the rule.
1. In Step 4, add additional metadata associated with the rule.
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
- Add Runbook URL, panel, dashboard, and alert IDs.
- Add custom labels.
1. In Step 5, add custom labels.
- Add custom labels selecting existing key-value pairs from the drop down, or add new labels by entering the new key or value .
1. Click **Save** to save the rule or **Save and exit** to save the rule and go back to the Alerting page.
@@ -37,18 +37,20 @@ Watch this video to learn more about how to create a Mimir managed alert rule: {
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
1. Click **New alert rule**. The new alerting rule page opens where the Grafana managed alerts option is selected by default.
1. In Step 1, select **Mimir or Loki alert** option.
1. In Step 1, add the rule name.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 2, select **Mimir or Loki alert** option.
- Next, select your Loki or Prometheus data source and add the query to evaluate.
- Enter a PromQL or LogQL expression to query. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
1. In Step 2, specify the alert evaluation interval.
1. In Step 3, specify the alert evaluation interval.
- In the **For** text box, specify the duration for which the condition must be true before an alert fires. If you specify `5m`, the condition must be true for 5 minutes before the alert fires.
> **Note:** Once a condition is met, the alert goes into the `Pending` state. If the condition remains active for the duration specified, the alert transitions to the `Firing` state, else it reverts to the `Normal` state.
1. In Step 3, add the rule name, namespace, rule group, as well as additional metadata associated with the rule.
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
1. In Step 4, add the namespace, rule group, as well as additional metadata associated with the rule.
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose. For more information, see [Grafana Mimir or Loki rule groups and namespaces]({{< relref "edit-mimir-loki-namespace-group/" >}}).
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
- Add Runbook URL, panel, dashboard, and alert IDs.
- Add custom labels.
1. In Step 5, add custom labels.
- Add custom labels selecting existing key-value pairs from the drop down, or add new labels by entering the new key or value .
1. Click **Save** to save the rule or **Save and exit** to save the rule and go back to the Alerting page.
1. Next, create a notification for the rule.
@@ -54,7 +54,7 @@ If Grafana has been set up to use an external image store, `upload_external_imag
# will be persisted to disk for up to temp_data_lifetime.
upload_external_image_storage = false
Restart Grafana for the changes to take affect.
Restart Grafana for the changes to take effect.
## Supported notifiers
@@ -88,8 +88,8 @@ Include images from URL refers to using the external image store.
Grafana provides the following metrics to observe the performance and failure rate of images in notifications.
For example, if a screenshot could not be taken within the expected time (10 seconds) then the counter `grafana_screenshot_failures_total` is updated.
- `grafana_screenshot_cache_hits_total`
- `grafana_screenshot_cache_misses_total`
- `grafana_alerting_image_cache_hits_total`
- `grafana_alerting_image_cache_misses_total`
- `grafana_screenshot_duration_seconds`
- `grafana_screenshot_failures_total`
- `grafana_screenshot_successes_total`
@@ -101,3 +101,14 @@ For example, if a screenshot could not be taken within the expected time (10 sec
- Images in notifications are not available for Grafana Mimir and Loki managed alert rules, or when Grafana is set up to send alert notifications to an external Alertmanager.
- When alerts generated by different alert rules are sent in a single notification, there may be screenshots for each alert rule. This happens if an alert group contains multiple alerting rules. The order the images are attached is random. If you need to guarantee the ordering of images, make sure that your alert groups contain a single alerting rule.
- Some contact points only handle a single image. In this case, the first image associated with an alert will be attached. Because the ordering is random, this may not always be an image for the same alert rule. If you need to guarantee you receive a screenshot for a particular rule, make sure that your alert groups contain a single alerting rule.
## Troubleshooting
If Grafana has been set up to send images in notifications, however notifications are still being received without images, then check the troubleshooting instructions below.
1. Check that Grafana has been set up as per the instructions
2. Check that the notifier supports images in notifications as per the table of supported notifiers
3. Enable debug logging in Grafana and look for logs with the logger `ngalert.image`
4. If the alert is not associated with a dashboard there will be logs for `Cannot take screenshot for alert rule as it is not associated with a dashboard`
5. If the alert is associated with a dashboard, but no panel in the dashboard, there will be logs for `Cannot take screenshot for alert rule as it is not associated with a panel`
6. If images cannot be taken because of mis-configuration or an issue with image rendering there will be logs for `Failed to take an image` including the Dashboard UID, Panel ID, and the error message
@@ -21,15 +21,25 @@ There are three options to choose from:
1. Use file provisioning to provision your Grafana Alerting resources, such as alert rules and contact points, through files on disk.
1. Provision your alerting resources using the Grafana HTTP API.
1. Provision your alerting resources using the Alerting Provisioning HTTP API.
For more information on the Grafana Alerting provisioning API, refer to [Alerting provisioning API](https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/).
For more information on the Alerting Provisioning HTTP API, refer to [Alerting provisioning API](https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/).
**Note:**
Typically, you cannot edit API-provisioned alert rules from the Grafana UI.
In order to enable editing, add the x-disable-provenance header to the following requests when creating or editing your alert rules in the API:
POST /api/v1/provisioning/alert-rules
PUT /api/v1/provisioning/alert-rules/{UID}
1. Provision your alerting resources using Terraform.
**Note:**
Currently, provisioning for Grafana Alerting supports alert rules, contact points, mute timings, and templates. Provisioned alerting resources can only be edited in the source that created them and not from within Grafana or any other source. For example, if you provision your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana.
Currently, provisioning for Grafana Alerting supports alert rules, contact points, mute timings, and templates. Provisioned alerting resources using file provisioning or Terraform can only be edited in the source that created them and not from within Grafana or any other source. For example, if you provision your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana.
**Useful Links:**
@@ -16,7 +16,7 @@ title: 'Annotations HTTP API'
# Annotations API
This is the API documentation for the new Grafana Annotations feature released in Grafana 4.6. Annotations are saved in the Grafana database (sqlite, mysql or postgres). Annotations can be organization annotations that can be shown on any dashboard by configuring an annotation data source - they are filtered by tags. Or they can be tied to a panel on a dashboard and are then only shown on that panel.
Annotations are saved in the Grafana database (sqlite, mysql or postgres). Annotations can be organization annotations that can be shown on any dashboard by configuring an annotation data source - they are filtered by tags. Or they can be tied to a panel on a dashboard and are then only shown on that panel.
> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "../../administration/roles-and-permissions/access-control/custom-role-actions-scopes/" >}}) for more information.
@@ -61,7 +61,7 @@ Grafana Enterprise adds the following features:
- [Custom branding]({{< relref "../setup-grafana/configure-grafana/configure-custom-branding/" >}}) to customize Grafana from the brand and logo to the footer links.
- [Usage insights]({{< relref "../dashboards/assess-dashboard-usage/" >}}) to understand how your Grafana instance is used.
- [Recorded queries]({{< relref "../administration/recorded-queries" >}}) to see trends over time for your data sources.
- [Vault integration]({{< relref "../setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/" >}}) to manage your configuration or provisioning secrets with Vault.
- [Vault integration]({{< relref "../setup-grafana/configure-security/configure-database-encryption/#encrypting-your-database-with-a-key-from-a-key-management-service-kms" >}}) to manage your configuration or provisioning secrets with Vault.
- [Auditing]({{< relref "../setup-grafana/configure-security/audit-grafana/" >}}) tracks important changes to your Grafana instance to help you manage and mitigate suspicious activity and meet compliance requirements.
- [Request security]({{< relref "../setup-grafana/configure-security/configure-request-security/" >}}) makes it possible to restrict outgoing requests from the Grafana server.
- [Settings updates at runtime]({{< relref "../setup-grafana/configure-grafana/settings-updates-at-runtime" >}}) allows you to update Grafana settings at runtime without requiring a restart.
@@ -55,9 +55,13 @@ Canvas introduces a new editing experience. You can now edit your canvas panel i
Related to a fresh look at panel editing, the context menu enables you to perform common tasks quickly and efficiently. Supported functionality includes opening / closing the inline editor, duplicating an element, deleting an element, and more.
The context menu is triggered by a right click action over the panel / over a given canvas element
The context menu is triggered by a right click action over the panel / over a given canvas element. When right clicking the panel, you are able to set a background image and easily add elements to the canvas.
{{< figure src="/static/img/docs/canvas-panel/canvas-context-menu-9-2-0.png" max-width="750px" caption="Canvas context menu" >}}
{{< figure src="/static/img/docs/canvas-panel/canvas-panel-context-menu-9-3-0.png" max-width="750px" caption="Canvas panel context menu" >}}
When right clicking an element, you are able to edit, delete, duplicate, and modify the element's layer positioning.
{{< figure src="/static/img/docs/canvas-panel/canvas-context-menu-9-2-0.png" max-width="750px" caption="Canvas element context menu" >}}
## Canvas Options
@@ -81,12 +81,13 @@ There are three map layer types to choose from in the Geomap visualization.
- [Heatmap]({{< relref "#heatmap-layer" >}}) visualizes a heatmap of the data.
- [GeoJSON]({{< relref "#geojson-layer" >}}) renders static data from a GeoJSON file.
There are also four alpha layer types.
There are also five alpha layer types.
- [Night / Day (alpha)]({{< relref "#night--day-layer-alpha" >}}) renders a night / day region.
- **Icon at last point (alpha)** renders an icon at the last data point.
- **Dynamic GeoJSON (alpha)** styles a GeoJSON file based on query results.
- **Route (alpha)** render data points as a route.
- [Photos layer (Alpha)]({{< relref "#photos-layer-alpha" >}}) renders a photo at each data point.
> **Note:** [Basemap layer types]({{< relref "#types-1" >}}) can also be added as layers. You can specify an opacity.
@@ -351,6 +352,34 @@ The Night / Day layer displays night and day regions based on the current time r
- [**Extensions for OpenLayers - DayNight**](https://viglino.github.io/ol-ext/examples/layer/map.daynight.html)
## Photos layer (Alpha)
The Photos layer renders a photo at each data point.
{{< figure src="/static/img/docs/geomap-panel/geomap-photos-9-3-0.png" max-width="1200px" caption="Geomap panel Photos" >}}
### Options
- **Image Source Field** select a string field containing image data in either of the following formats
- **Image URLs**
- **Base64 encoded** image binary ("data:image/png;base64,...")
- **Kind** select the frame style around the images
- **Square**
- **Circle**
- **Anchored**
- **Folio**
- **Crop** toggle if the images are cropped to fit
- **Shadow** toggle a box shadow behind the images
- **Border** set the border size around images
- **Border color** set the border color around images
- **Radius** set the overall size of images in pixels
{{< figure src="/static/img/docs/geomap-panel/geomap-photos-options-9-3-0.png" max-width="1200px" caption="Geomap panel Photos options" >}}
### More information
- [**Extensions for OpenLayers - Image Photo Style**](http://viglino.github.io/ol-ext/examples/style/map.style.photo.html)
## Map Controls
The map controls section contains various options for map information and tool overlays.
@@ -21,8 +21,5 @@ e2e.scenario({
e2e.components.Search.folderContent('General').should('be.visible');
e2e.components.Search.dashboardItem('E2E Test - Import Dashboard').should('be.visible');
// verify the imported dashboard is the only dashboard present in the folder
e2e().get('[data-testid^="data-testid Dashboard search item "]').should('have.length', 1);
},
});
@@ -72,10 +72,6 @@ describe('Loki query builder', () => {
e2e().contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('not.exist');
e2e().contains(finalQuery).should('be.visible');
// Toggle raw query
e2e().contains('label', 'Raw query').click();
e2e().contains('Raw query').should('have.length', 1);
// Change to code editor
e2e().contains('label', 'Code').click();
// We need to test this manually because the final query is split into separate DOM elements using e2e().contains(finalQuery).should('be.visible'); does not detect the query.
+2 -1
View File
@@ -2,4 +2,5 @@
. scripts/grafana-server/variables
./e2e/run-suite verify/specs
# The run-suite script requires a second argument to determine if videos should be recorded
./e2e/run-suite verify/specs true
+14
View File
@@ -0,0 +1,14 @@
build: build-html build-txt
build-html:
npx mjml \
--config.beautify true \
--config.minify false \
--config.validationLevel=strict \
--config.keepComments=false \
./templates/*.mjml --output ../public/emails/
build-txt:
npx grunt
.PHONY: build build-html build-txt
-688
View File
@@ -1,688 +0,0 @@
/**********************************************
* Ink v1.0.5 - Copyright 2013 ZURB Inc *
**********************************************/
/* Client-specific Styles & Reset */
#outlook a {
padding:0;
}
body{
width:100% !important;
min-width: 100%;
-webkit-text-size-adjust:100%;
-ms-text-size-adjust:100%;
margin:0;
padding:0;
}
.ExternalClass {
width:100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
#backgroundTable {
margin:0;
padding:0;
width:100% !important;
line-height: 100% !important;
}
img {
outline:none;
text-decoration:none;
-ms-interpolation-mode: bicubic;
width: auto;
float: left;
clear: both;
display: block;
}
center {
width: 100%;
min-width: 580px;
}
a img {
border: none;
}
p {
margin: 0 0 0 10px;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
td {
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
border-collapse: collapse !important;
}
table, tr, td {
padding: 0;
vertical-align: top;
text-align: left;
}
hr {
color: #d9d9d9;
background-color: #d9d9d9;
height: 1px;
border: none;
}
/* Responsive Grid */
table.body {
height: 100%;
width: 100%;
}
table.container {
width: 580px;
margin: 0 auto;
text-align: inherit;
}
table.row {
padding: 0px;
width: 100%;
position: relative;
}
table.container table.row {
display: block;
}
td.wrapper {
padding: 10px 20px 0px 0px;
position: relative;
}
table.columns,
table.column {
margin: 0 auto;
}
table.columns td,
table.column td {
padding: 0px 0px 10px;
}
table.columns td.sub-columns,
table.column td.sub-columns,
table.columns td.sub-column,
table.column td.sub-column {
padding-right: 10px;
}
td.sub-column, td.sub-columns {
min-width: 0px;
}
table.row td.last,
table.container td.last {
padding-right: 0px;
}
table.one { width: 30px; }
table.two { width: 80px; }
table.three { width: 130px; }
table.four { width: 180px; }
table.five { width: 230px; }
table.six { width: 280px; }
table.seven { width: 330px; }
table.eight { width: 380px; }
table.nine { width: 430px; }
table.ten { width: 480px; }
table.eleven { width: 530px; }
table.twelve { width: 580px; }
table.one center { min-width: 30px; }
table.two center { min-width: 80px; }
table.three center { min-width: 130px; }
table.four center { min-width: 180px; }
table.five center { min-width: 230px; }
table.six center { min-width: 280px; }
table.seven center { min-width: 330px; }
table.eight center { min-width: 380px; }
table.nine center { min-width: 430px; }
table.ten center { min-width: 480px; }
table.eleven center { min-width: 530px; }
table.twelve center { min-width: 580px; }
table.one .panel center { min-width: 10px; }
table.two .panel center { min-width: 60px; }
table.three .panel center { min-width: 110px; }
table.four .panel center { min-width: 160px; }
table.five .panel center { min-width: 210px; }
table.six .panel center { min-width: 260px; }
table.seven .panel center { min-width: 310px; }
table.eight .panel center { min-width: 360px; }
table.nine .panel center { min-width: 410px; }
table.ten .panel center { min-width: 460px; }
table.eleven .panel center { min-width: 510px; }
table.twelve .panel center { min-width: 560px; }
.body .columns td.one,
.body .column td.one { width: 8.333333%; }
.body .columns td.two,
.body .column td.two { width: 16.666666%; }
.body .columns td.three,
.body .column td.three { width: 25%; }
.body .columns td.four,
.body .column td.four { width: 33.333333%; }
.body .columns td.five,
.body .column td.five { width: 41.666666%; }
.body .columns td.six,
.body .column td.six { width: 50%; }
.body .columns td.seven,
.body .column td.seven { width: 58.333333%; }
.body .columns td.eight,
.body .column td.eight { width: 66.666666%; }
.body .columns td.nine,
.body .column td.nine { width: 75%; }
.body .columns td.ten,
.body .column td.ten { width: 83.333333%; }
.body .columns td.eleven,
.body .column td.eleven { width: 91.666666%; }
.body .columns td.twelve,
.body .column td.twelve { width: 100%; }
td.offset-by-one { padding-left: 50px; }
td.offset-by-two { padding-left: 100px; }
td.offset-by-three { padding-left: 150px; }
td.offset-by-four { padding-left: 200px; }
td.offset-by-five { padding-left: 250px; }
td.offset-by-six { padding-left: 300px; }
td.offset-by-seven { padding-left: 350px; }
td.offset-by-eight { padding-left: 400px; }
td.offset-by-nine { padding-left: 450px; }
td.offset-by-ten { padding-left: 500px; }
td.offset-by-eleven { padding-left: 550px; }
td.expander {
visibility: hidden;
width: 0px;
padding: 0 !important;
}
table.columns .text-pad,
table.column .text-pad {
padding-left: 10px;
padding-right: 10px;
}
table.columns .left-text-pad,
table.columns .text-pad-left,
table.column .left-text-pad,
table.column .text-pad-left {
padding-left: 10px;
}
table.columns .right-text-pad,
table.columns .text-pad-right,
table.column .right-text-pad,
table.column .text-pad-right {
padding-right: 10px;
}
/* Block Grid */
.block-grid {
width: 100%;
max-width: 580px;
}
.block-grid td {
display: inline-block;
padding:10px;
}
.two-up td {
width:270px;
}
.three-up td {
width:173px;
}
.four-up td {
width:125px;
}
.five-up td {
width:96px;
}
.six-up td {
width:76px;
}
.seven-up td {
width:62px;
}
.eight-up td {
width:52px;
}
/* Alignment & Visibility Classes */
table.center, td.center {
text-align: center;
}
h1.center,
h2.center,
h3.center,
h4.center,
h5.center,
h6.center {
text-align: center;
}
span.center {
display: block;
width: 100%;
text-align: center;
}
img.center {
margin: 0 auto;
float: none;
}
.show-for-small,
.hide-for-desktop {
display: none;
}
/* Typography */
body, table.body, h1, h2, h3, h4, h5, h6, p, td {
color: #222222;
font-family: "Helvetica", "Arial", sans-serif;
font-weight: normal;
padding:0;
margin: 0;
text-align: left;
line-height: 1.3;
}
h1, h2, h3, h4, h5, h6 {
word-break: normal;
}
h1 {font-size: 40px;}
h2 {font-size: 36px;}
h3 {font-size: 32px;}
h4 {font-size: 28px;}
h5 {font-size: 24px;}
h6 {font-size: 20px;}
body, table.body, p, td {font-size: 14px;line-height:19px;}
p.lead, p.lede, p.leed {
font-size: 18px;
line-height:21px;
}
p {
margin-bottom: 10px;
}
small {
font-size: 10px;
}
a {
color: #2ba6cb;
text-decoration: none;
}
a:hover {
color: #2795b6 !important;
}
a:active {
color: #2795b6 !important;
}
a:visited {
color: #2ba6cb !important;
}
h1 a,
h2 a,
h3 a,
h4 a,
h5 a,
h6 a {
color: #2ba6cb;
}
h1 a:active,
h2 a:active,
h3 a:active,
h4 a:active,
h5 a:active,
h6 a:active {
color: #2ba6cb !important;
}
h1 a:visited,
h2 a:visited,
h3 a:visited,
h4 a:visited,
h5 a:visited,
h6 a:visited {
color: #2ba6cb !important;
}
/* Panels */
.panel {
background: #f2f2f2;
border: 1px solid #d9d9d9;
padding: 10px !important;
}
.sub-grid table {
width: 100%;
}
.sub-grid td.sub-columns {
padding-bottom: 0;
}
/* Buttons */
table.button,
table.tiny-button,
table.small-button,
table.medium-button,
table.large-button {
width: 100%;
overflow: hidden;
}
table.button td,
table.tiny-button td,
table.small-button td,
table.medium-button td,
table.large-button td {
display: block;
width: auto !important;
text-align: center;
background: #2ba6cb;
border: 1px solid #2284a1;
color: #ffffff;
padding: 8px 0;
}
table.tiny-button td {
padding: 5px 0 4px;
}
table.small-button td {
padding: 8px 0 7px;
}
table.medium-button td {
padding: 12px 0 10px;
}
table.large-button td {
padding: 21px 0 18px;
}
table.button td a,
table.tiny-button td a,
table.small-button td a,
table.medium-button td a,
table.large-button td a {
font-weight: bold;
text-decoration: none;
font-family: Helvetica, Arial, sans-serif;
color: #ffffff;
font-size: 16px;
}
table.tiny-button td a {
font-size: 12px;
font-weight: normal;
}
table.small-button td a {
font-size: 16px;
}
table.medium-button td a {
font-size: 20px;
}
table.large-button td a {
font-size: 24px;
}
table.button:hover td,
table.button:visited td,
table.button:active td {
background: #2795b6 !important;
}
table.button:hover td a,
table.button:visited td a,
table.button:active td a {
color: #fff !important;
}
table.button:hover td,
table.tiny-button:hover td,
table.small-button:hover td,
table.medium-button:hover td,
table.large-button:hover td {
background: #2795b6 !important;
}
table.button:hover td a,
table.button:active td a,
table.button td a:visited,
table.tiny-button:hover td a,
table.tiny-button:active td a,
table.tiny-button td a:visited,
table.small-button:hover td a,
table.small-button:active td a,
table.small-button td a:visited,
table.medium-button:hover td a,
table.medium-button:active td a,
table.medium-button td a:visited,
table.large-button:hover td a,
table.large-button:active td a,
table.large-button td a:visited {
color: #ffffff !important;
}
table.secondary td {
background: #e9e9e9;
border-color: #d0d0d0;
color: #555;
}
table.secondary td a {
color: #555;
}
table.secondary:hover td {
background: #d0d0d0 !important;
color: #555;
}
table.secondary:hover td a,
table.secondary td a:visited,
table.secondary:active td a {
color: #555 !important;
}
table.success td {
background: #5da423;
border-color: #457a1a;
}
table.success:hover td {
background: #457a1a !important;
}
table.alert td {
background: #c60f13;
border-color: #970b0e;
}
table.alert:hover td {
background: #970b0e !important;
}
table.radius td {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
table.round td {
-webkit-border-radius: 500px;
-moz-border-radius: 500px;
border-radius: 500px;
}
/* Outlook First */
body.outlook p {
display: inline !important;
}
/* Media Queries */
@media only screen and (max-width: 600px) {
table[class="body"] img {
}
table[class="body"] center {
min-width: 0 !important;
}
table[class="body"] .container {
width: 95% !important;
}
table[class="body"] .row {
width: 100% !important;
display: block !important;
}
table[class="body"] .wrapper {
display: block !important;
padding-right: 0 !important;
}
table[class="body"] .columns,
table[class="body"] .column {
table-layout: fixed !important;
float: none !important;
width: 100% !important;
padding-right: 0px !important;
padding-left: 0px !important;
display: block !important;
}
table[class="body"] .wrapper.first .columns,
table[class="body"] .wrapper.first .column {
display: table !important;
}
table[class="body"] table.columns td,
table[class="body"] table.column td {
width: 100% !important;
}
table[class="body"] .columns td.one,
table[class="body"] .column td.one { width: 8.333333% !important; }
table[class="body"] .columns td.two,
table[class="body"] .column td.two { width: 16.666666% !important; }
table[class="body"] .columns td.three,
table[class="body"] .column td.three { width: 25% !important; }
table[class="body"] .columns td.four,
table[class="body"] .column td.four { width: 33.333333% !important; }
table[class="body"] .columns td.five,
table[class="body"] .column td.five { width: 41.666666% !important; }
table[class="body"] .columns td.six,
table[class="body"] .column td.six { width: 50% !important; }
table[class="body"] .columns td.seven,
table[class="body"] .column td.seven { width: 58.333333% !important; }
table[class="body"] .columns td.eight,
table[class="body"] .column td.eight { width: 66.666666% !important; }
table[class="body"] .columns td.nine,
table[class="body"] .column td.nine { width: 75% !important; }
table[class="body"] .columns td.ten,
table[class="body"] .column td.ten { width: 83.333333% !important; }
table[class="body"] .columns td.eleven,
table[class="body"] .column td.eleven { width: 91.666666% !important; }
table[class="body"] .columns td.twelve,
table[class="body"] .column td.twelve { width: 100% !important; }
table[class="body"] td.offset-by-one,
table[class="body"] td.offset-by-two,
table[class="body"] td.offset-by-three,
table[class="body"] td.offset-by-four,
table[class="body"] td.offset-by-five,
table[class="body"] td.offset-by-six,
table[class="body"] td.offset-by-seven,
table[class="body"] td.offset-by-eight,
table[class="body"] td.offset-by-nine,
table[class="body"] td.offset-by-ten,
table[class="body"] td.offset-by-eleven {
padding-left: 0 !important;
}
table[class="body"] table.columns td.expander {
width: 1px !important;
}
table[class="body"] .right-text-pad,
table[class="body"] .text-pad-right {
padding-left: 10px !important;
}
table[class="body"] .left-text-pad,
table[class="body"] .text-pad-left {
padding-right: 10px !important;
}
table[class="body"] .hide-for-small,
table[class="body"] .show-for-desktop {
display: none !important;
}
table[class="body"] .show-for-small,
table[class="body"] .hide-for-desktop {
display: inherit !important;
}
}
-196
View File
@@ -1,196 +0,0 @@
body, table.body, h1, h2, h3, h4, h5, h6, p, td {
font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
h1 {font-size: 40px;}
h2 {font-size: 36px;}
h3 {
font-size: 22px;
margin-top: 10px;
margin-bottom: 10px;
}
h4 {font-size: 20px;}
h5 {font-size: 18px;}
h6 {font-size: 16px;}
.emphasis {
font-weight: 600;
}
a {
color: #E67612;
text-decoration: none;
}
a:hover {
color: #ff8f2b !important;
}
a:active {
color: #F2821E !important;
}
a:visited {
color: #E67612 !important;
}
table.facebook td {
background: #3b5998;
border-color: #2d4473;
}
table.facebook:hover td {
background: #2d4473 !important;
}
table.twitter td {
background: #00acee;
border-color: #0087bb;
}
table.twitter:hover td {
background: #0087bb !important;
}
table.google-plus td {
background-color: #DB4A39;
border-color: #CC0000;
}
table.google-plus:hover td {
background: #CC0000 !important;
}
.template-label {
color: #ffffff;
font-weight: bold;
font-size: 11px;
}
.callout .wrapper {
padding-bottom: 20px;
}
.callout .panel {
background: #ECF8FF;
border-color: #b9e5ff;
}
.header {
margin-top:25px;
margin-bottom: 25px;
}
.data {
font-size: 16px;
}
.footer {
background-color: #2e2e2e;
color: #999999;
margin: 0 auto;
width: 100%;
}
@media only screen and (max-width: 600px) {
table[class="body"] .right-text-pad {
padding-left: 10px !important;
}
table[class="body"] .left-text-pad {
padding-right: 10px !important;
}
.logo {
margin-left: 10px;
}
}
table.better-button {
margin-top: 10px;
margin-bottom: 20px;
}
table.columns td.better-button {
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
padding-bottom: 0px;
}
.better-button a {
text-decoration: none;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
padding: 12px 25px;
border: 1px solid #ff8f2b;
display: inline-block;
color: #FFF;
}
.better-button:hover a {
color: #FFFFFF !important;
background-color: #F2821E;
border: 1px solid #F2821E;
}
.better-button:visited a {
color: #FFFFFF !important;
}
.better-button:active a {
color: #FFFFFF !important;
}
table.better-button-alt {
margin-top: 10px;
margin-bottom: 20px;
}
table.columns td.better-button-alt {
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
padding-bottom: 0px;
}
.better-button-alt a {
text-decoration: none;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
padding: 12px 25px;
border: 1px solid #ff8f2b;
background-color: #EFEFEF;
display: inline-block;
color: #ff8f2b;
}
.better-button-alt:hover a {
color: #ff8f2b !important;
background-color: #DDDDDD;
border: 1px solid #F2821E;
}
.better-button-alt:visited a {
color: #ff8f2b !important;
}
.better-button-alt:active a {
color: #ff8f2b !important;
}
.verification-code {
background-color: #EEEEEE;
padding: 3px;
margin: 8px;
display: inline-block;
font-weight: bold;
font-size: 20px;
}
+4 -7
View File
@@ -1,8 +1,5 @@
default:
- 'clean'
- 'assemble'
- 'replace'
- 'uncss'
- 'processhtml'
- 'premailer'
- 'clean'
- 'assemble'
- 'replace'
- 'copy'
+1 -10
View File
@@ -2,21 +2,12 @@ module.exports = function () {
'use strict';
return {
options: {
partials: ['templates/partials/*.hbs'],
helpers: ['templates/helpers/**/*.js'],
data: [],
flatten: true,
},
html: {
options: {
layout: 'templates/layouts/default.html',
},
src: ['templates/*.html'],
dest: 'dist/',
},
txt: {
options: {
layout: 'templates/layouts/default.txt',
layout: 'templates/partials/layout/default.txt',
ext: '.txt',
},
src: ['templates/*.txt'],
+11
View File
@@ -0,0 +1,11 @@
module.exports = function () {
'use strict';
return {
txt: {
expand: true,
cwd: 'dist',
src: ['**.txt'],
dest: '../public/emails/',
},
};
};
-31
View File
@@ -1,31 +0,0 @@
module.exports = {
html: {
options: {
verbose: true,
removeComments: true,
},
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'dist', // Src matches are relative to this path.
src: ['*.html'], // Actual pattern(s) to match.
dest: '../public/emails/', // Destination path prefix.
},
],
},
txt: {
options: {
verbose: true,
mode: 'txt',
lineLength: 90,
},
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'dist', // Src matches are relative to this path.
src: ['*.txt'], // Actual patterns to match.
dest: '../public/emails/', // Destination path prefix.
},
],
},
};
-12
View File
@@ -1,12 +0,0 @@
module.exports = {
dist: {
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'dist', // Src matches are relative to this path.
src: ['*.html'], // Actual pattern(s) to match.
dest: 'dist/', // Destination path prefix.
},
],
},
};
+1 -1
View File
@@ -1,7 +1,7 @@
module.exports = {
dist: {
overwrite: true,
src: ['dist/*.html', 'dist/*.txt'],
src: ['dist/*.txt'],
replacements: [
{
from: '[[',
-9
View File
@@ -1,9 +0,0 @@
module.exports = {
dist: {
src: ['dist/*.html'],
dest: 'dist/css/tidy.css',
options: {
report: 'min', // optional: include to report savings
},
},
};
-16
View File
@@ -1,16 +0,0 @@
module.exports = {
src: {
files: [
//what are the files that we want to watch
'assets/css/*.css',
'templates/**/*.html',
'templates/**/*.txt',
'grunt/*.js',
],
tasks: ['default'],
options: {
nospawn: true,
livereload: false,
},
},
};
+9 -18
View File
@@ -1,26 +1,17 @@
{
"name": "Grafana-Email-Campaign",
"name": "grafana-email-campaign",
"version": "1.0.0",
"description": "Grafana Email templates based on Zurb Ink",
"repository": "dnnsldr/",
"author": {
"name": "dnnsldr",
"email": "delder@riester.com",
"url": "https://github.com/dnnsldr"
},
"scripts": {
"build": "grunt",
"start": "grunt watch"
},
"description": "Grafana Email templates based on MJML",
"author": "Grafana Labs",
"devDependencies": {
"grunt": "1.0.1",
"grunt-premailer": "1.1.0",
"grunt-processhtml": "^0.4.2",
"grunt-uncss": "0.9.0",
"load-grunt-config": "3.0.1",
"grunt-assemble": "0.6.3",
"grunt-cli": "^1.4.3",
"grunt-contrib-clean": "2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-watch": "1.1.0",
"grunt-text-replace": "0.4.0",
"grunt-assemble": "0.6.3",
"grunt-contrib-clean": "2.0.0"
"load-grunt-config": "3.0.1",
"mjml": "^4.13.0"
}
}
-134
View File
@@ -1,134 +0,0 @@
[[Subject .Subject "[[.Title]]"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
<h3 style="/*text-align:center*/;color: [[.SeverityColor]]; font-weight: bold; font-style: italic;">[[.Title]]</h3>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row" >
<tr>
<td class="last">
<table class="twelve columns">
<tr>
<td class="center">
<p style="/*text-align:center*/">[[.Message]]</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
[[if ne .Error "" ]]
<table class="row" >
<tr>
<td class="last">
<center>
<table class="twelve columns" >
<tr>
<td class="twelve last">
<h5 style="font-weight: bold;">Error message</h5>
</td>
</tr>
<tr>
<td class="twelve last">
<p>[[.Error]]</p>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>
[[end]]
[[if ne .State "ok" ]]
<table class="row" >
<tr>
<td class="last">
<center>
<table class="twelve columns" >
<tr>
<td class="six">
<h5 style="font-weight: bold;">Metric name</h5>
</td>
<td class="six last" style="text-align: right; width:100px;">
<h5 style="font-weight: bold;text-align: right;">Value</h5>
</td>
</tr>
[[range .EvalMatches]]
<tr>
<td class="six">
<h5 class="data">[[.Metric]]</h5>
</td>
<td class="six last" style="text-align: right; width:100px;">
<h5 class="data" style="text-align: right;">[[.Value]]</h5>
</td>
</tr>
[[end]]
</table>
</center>
</td>
</tr>
</table>
[[end]]
<table class="row" >
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
[[if ne .ImageLink "" ]]
<img src="[[.ImageLink]]" alt="Alerting Panel"/>
[[end]]
[[if ne .EmbeddedImage "" ]]
<img src="cid:[[.EmbeddedImage]]" alt="Alerting Panel"/>
[[end]]
</td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center six">
<table class="better-button" align="center" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" class="better-button" bgcolor="#ff8f2b">
<a rel="noopener noreferrer" href="[[.RuleUrl]]" target="_blank">View your Alert rule</a>
</td>
</tr>
</table>
</td>
<td class="center six">
<table class="better-button" align="center" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" class="better-button-alt" bgcolor="#efefef">
<a rel="noopener noreferrer" href="[[.AlertPageUrl]]" target="_blank"> Go to the Alerts page</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
-26
View File
@@ -1,26 +0,0 @@
[[Subject .Subject "[[.Title]]"]]
[[.Title]]
----------------
[[.Message]]
[[if ne .Error "" ]]
Error message:
[[.Error]]
[[end]]
[[if ne .State "ok" ]]
[[range .EvalMatches]]
Metric name:
[[.Metric]]
Value:
[[.Value]]
[[end]]
[[end]]
View your Alert rule:
[[.RuleUrl]]"
Go to the Alerts page:
[[.AlertPageUrl]]
-47
View File
@@ -1,47 +0,0 @@
<!-- This email is sent when an existing user is added to an organization -->
[[Subject .Subject "[[.InvitedBy]] has added you to the [[.OrgName]] organization"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td>
<h4 class="center">You have been added to [[.OrgName]]</h4>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
<p><b>[[.InvitedBy]]</b> has added you to the <b>[[.OrgName]]</b> organization in Grafana.
<p>Once logged in, [[.OrgName]] will be available in the left side menu, in the dropdown below your username.</p>
</td>
<td class="expander"></td>
</tr>
<tr>
<td class="center">
<table class="better-button" align="center" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" class="better-button" bgcolor="#ff8f2b"><a rel="noopener noreferrer" href="[[.AppUrl]]" target="_blank">Log in now</a></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
+40
View File
@@ -0,0 +1,40 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject! Use the HTML comment below ⬇ -->
<mj-title>
{{ Subject .Subject "{{ .InvitedBy }} has added you to the {{ .OrgName }} organization" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section background-color="#22252b" border="1px solid #2f3037">
<mj-column>
<mj-text>
<h2>You have been added to {{ .OrgName }}</h2>
<strong>{{ .InvitedBy }}</strong> has added you to the <strong>{{ .OrgName }}</strong> organization in Grafana.
</mj-text>
<mj-text>
Once logged in, <strong>{{ .OrgName }}</strong> will be available to switch to in the user interface.
</mj-text>
<mj-text>
Log in now by clicking the link below:
</mj-text>
<mj-button href="{{ .AppUrl }}">
Login to Grafana
</mj-button>
<mj-text>
You can also copy and paste this link into your browser directly:
</mj-text>
<mj-text>
<a rel="noopener" href="{{ .AppUrl }}">{{ .AppUrl }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
+1 -1
View File
@@ -6,4 +6,4 @@ You have been added to [[.OrgName]]
Once logged in, [[.OrgName]] will be available in the left side menu, in the dropdown below your username.
Log in now:
[[.AppUrl]]
[[.AppUrl]]
-161
View File
@@ -1,161 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width"/>
<!-- build:css css/tidy.css -->
<link inline rel="stylesheet" href="../assets/css/ink.css">
<link inline rel="stylesheet" href="../assets/css/style.css">
<!-- /build -->
</head>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" class="main" style="background: #2e2e2e; height: 100% !important; margin: 0 auto; padding: 0; width: 100% !important" bgcolor="#2e2e2e"><style type="text/css">
body {
height: 100% !important; width: 100% !important;
}
body .copy {
-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
}
.ExternalClass {
width: 100%;
}
.ExternalClass {
line-height: 100%;
}
img {
-ms-interpolation-mode: bicubic;
}
img {
border: 0 !important; outline: none !important; text-decoration: none !important;
}
a:hover {
text-decoration: underline;
}
td[class="stack-column-center"] {
text-align: center !important;
}
@media (max-width: 600px) {
table[class="email-container"] {
width: 95% !important;
}
img[class="fluid"] {
width: 100% !important; max-width: 100% !important; height: auto !important; margin: auto !important;
}
img[class="fluid-centered"] {
width: 100% !important; max-width: 100% !important; height: auto !important; margin: auto !important;
}
img[class="fluid-centered"] {
margin: auto !important;
}
td[class="comms-content"] {
padding: 20px !important;
}
td[class="stack-column"] {
display: block !important; width: 100% !important; direction: ltr !important;
}
td[class="stack-column-center"] {
display: block !important; width: 100% !important; direction: ltr !important;
}
td[class="stack-column-center"] {
text-align: center !important;
}
td[class="copy"] {
font-size: 14px !important; line-height: 24px !important; padding: 0 30px !important;
}
td[class="copy -center"] {
font-size: 14px !important; line-height: 24px !important; padding: 0 30px !important;
}
td[class="copy -bold"] {
font-size: 14px !important; line-height: 24px !important; padding: 0 30px !important;
}
td[class="small-text"] {
font-size: 14px !important; line-height: 24px !important; padding: 0 30px !important;
}
td[class="mini-centered-text"] {
font-size: 14px !important; line-height: 24px !important; padding: 15px 30px !important;
}
td[class="copy -padd"] {
padding: 0 40px !important;
}
span[class="sep"] {
display: none !important;
}
td[class="mb-hide"] {
display: none !important; height: 0 !important;
}
td[class="spacer mb-shorten"] {
height: 25px !important;
}
.two-up td {
width:270px;
}
}
</style>
<table class="body" style="background: #2e2e2e;">
<tr>
<td class="center" align="center" valign="top">
<center>
<table class="row header">
<tr>
<td class="center" align="center">
<center>
<table class="container">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="twelve sub-columns center">
<img class="logo" src="https://grafana.com/static/assets/img/logo_new_transparent_200x48.png" style="width: 200px; float: none; display: inline">
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>
<table class="container" style="background-color: #efefef;" width="600">
<tr>
<td height="2" class="spacer mb-shorten" style="font-size: 0; line-height: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; vertical-align: top; border: 0; background: linear-gradient(to right, #ffed00 0%, #f26529 75%); height: 2px !important" valign="top"> </td>
</tr>
<tr>
<td class="mini-centered-text" style="color: #343b41; font: 400 16px/27px 'Helvetica Neue', Helvetica, Arial, sans-serif; mso-table-lspace: 0pt; mso-table-rspace: 0pt; padding: 25px 35px; text-align: center; vertical-align: top" align="center" valign="top">
{{> body }}
<!-- container end below -->
</td>
</tr>
</table>
<!-- footer -->
<table class="footer center">
<tr>
<td class="wrapper last">
<table class="twelve columns center">
<tr>
<td class="twelve" align="center">
<center>
<p style="text-align: center; font-size: 12px; color: #999999;">
Sent by <a href="[[.AppUrl]]">Grafana v[[.BuildVersion]]</a>
<br />&copy; 2022 Grafana Labs
</p>
</center>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</td>
</tr>
</table>
</body>
</html>
-3
View File
@@ -1,3 +0,0 @@
{{> body }}
Sent by Grafana v[[.BuildVersion]] (c) 2022 Grafana Labs
-49
View File
@@ -1,49 +0,0 @@
<!-- This email is sent when user who does not already exist in Grafana is added to an organization -->
[[Subject .Subject "[[.InvitedBy]] has invited you to join Grafana"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td>
<h4 class="center">You're invited to join [[.OrgName]]</h4>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
<p>You've been invited to join the <b>[[.OrgName]]</b> organization by <b>[[.InvitedBy]]</b>. To accept your invitation and join the team, please click the link below:</p>
</td>
</tr>
<tr>
<td class="center">
<table class="better-button" align="center" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" class="better-button" bgcolor="#ff8f2b"><a rel="noopener noreferrer" href="[[.LinkUrl]]" target="_blank">Accept Invitation</a></td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="center">
<p>You can also copy and paste this link into your browser directly: <a href="[[.LinkUrl]]">[[.LinkUrl]]</a></p>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
+36
View File
@@ -0,0 +1,36 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject "{{ .InvitedBy }} has invited you to join Grafana" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section background-color="#22252b" border="1px solid #2f3037">
<mj-column>
<mj-text>
<h2>You're invited to join {{ .OrgName }}</h2>
</mj-text>
<mj-text>
You've been invited to join the <strong>{{ .OrgName }}</strong> organization by <strong>{{ .InvitedBy }}</strong>. To accept your invitation and join the team, please click the link below:
</mj-text>
<mj-button href="{{ .LinkUrl }}">
Accept Invitation
</mj-button>
<mj-text>
You can also copy and paste this link into your browser directly:
</mj-text>
<mj-text>
<a rel="noopener" href="{{ .LinkUrl }}">{{ .LinkUrl }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
-271
View File
@@ -1,271 +0,0 @@
<!-- The template body needs to be wrapped in div to prevent Premailer from adding </tr></td> tags which breaks the HTML structure -->
<div>
[[Subject .Subject "[[.Title]]"]]
[[ define "__text_values_list" ]][[ $len := len .Values ]][[ if $len ]][[ $first := gt $len 1 ]][[ range $refID, $value := .Values -]]
[[ $refID ]]=[[ $value ]][[ if $first ]], [[ end ]][[ $first = false ]][[ end -]]
[[ else ]][no value][[ end ]][[ end ]]
[[ define "alert" ]]
[[ if ne .ImageURL "" ]]
<tr>
<td colspan="2" class="value">
<img src="[[.ImageURL]]" class="fluid-centered" alt="Alerting Panel" />
</td>
</tr>
[[ end ]]
[[ if ne .EmbeddedImage "" ]]
<tr>
<td colspan="2" class="value">
<img src="cid:[[.EmbeddedImage]]" alt="Alerting Chart Attached Below" />
</td>
</tr>
[[ end ]]
<tr>
<td colspan="2" class="value">
<span class="value-heading">Value:</span> <span class="value-value">[[ template "__text_values_list" . ]]</span>
</td>
</tr>
[[ if gt (len .Annotations.SortedPairs) 0 ]]
<tr>
<td colspan="2" class="annotations">
[[ range .Annotations.SortedPairs ]]
<p><span class="annotations-heading">[[ .Name ]]:</span> <span class="annotations-value">[[ .Value ]]</span></p>
[[ end ]]
</td>
</tr>
[[ end ]]
<tr>
<td colspan="2">
<span class="labels-heading">Labels:</span>
<ul class="labels-list">
[[ range .Labels.SortedPairs ]]<li>[[ .Name ]]: [[ .Value ]]</li>[[ end ]]
</ul>
</td>
</tr>
<tr>
<td colspan="2" class="actions">
[[ if .SilenceURL ]]
<a
href="[[ .SilenceURL ]]"
class="button"
>
<img
alt=""
height="14"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAF1SURBVHgBrZLNTsJAEMf/2wYTPfEI9Q1qvBgjsEl5gB498gj1SDHpEKUckaMn4eiNFyAp4cJN30CPHrn5BV1noTWlFD3oJNuZ3Z39zUcH+A9pUffJpzAoOO/xuvvprZHooYCgLISoa7FyFSCbdOXuApj6M43GUVXWhYZUpKP3k1NZ14+kAOYChleVjnssK/ezKHrLAkQuZWIVKCgKyW+n55cUciZClzLoUPOiqISVlPB+s6ZulnNN/ihG3GfT84jKOwGvMO0krVEewoBoHeTA2glIhRuno7WzkH0Yc633sCz/CoiVshdYRGxGKYSo9ahgHnEPoqzvdxP1b/sEHtgsF2e12ditDD6gPE59XgIO8ytfTlbM1DiTzjk7WQvEYgllZ5fSXeE7vnfTOdkC1GqOBSFO2Mk22JG1TB4l+1VzX/IQgQJpBaHHsB6bA47+rNOHUI1O4A/zw2YWAaaT8UyPNkdcZ6JUs0P+7eouGXuO3WC7j7/KF29iokiLUdaFAAAAAElFTkSuQmCC"
class="button-img"
width="14"
/>
Silence
</a>
[[ end ]]
[[ if .Annotations.runbook_url ]]
<a
href="[[ .Annotations.runbook_url ]]"
class="button"
>
<img
class="button-img"
alt=""
height="14"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADaSURBVHgBrVNLDoIwFJwq0bjTG+ARvIGeQI/ADdSVARY8oki8jZxEbyDewLUfahttAoEWDM7m9bVvJtN0CrQEyzdENLyjt2RgtoFzjcgl1XTyJw/0T4K8ghmBH8Zz1VhqsaHtVBT7CYwP5KY6tk+xw3k2Kgl0YdmyKrIYvEjB73EqbI+rBC1owMDXGdjws0aqm9MK7Mg7ogE6aInWAqUreLQPanJgdtAgB2YHIgeTuhxUOlBPNcBvKPwFT4RHbnDgLOpNw3EEaxEFblJwIPECZhw8MZAlQkX+C95zCzqWDYrK2AAAAABJRU5ErkJggg=="
width="14"
/>
View Runbook
</a>
[[ end ]]
[[ if .DashboardURL]]
<a
href="[[ .DashboardURL ]]"
class="button"
>
<img
alt=""
height="14"
class="button-img"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAE9SURBVHgBrVLNWcMwDH220/bjhEdIR2AC6ASMQEeAU6G9+FLycQojdAUmgE7ACGSEcEybRkj5cUKbnFp9X2JZ8nuypQecaUp+Kxf98BIeJ3cwNxqZDRB89mCTtXuZBvVGwBsCtiUrkYVS8RgHmzeVFB4Lwm9d9Y6XB/EbAhCK7atbbcRfuCjkRNwtt6fs4825RPyli4SkJNA40/wNFCm7cC6sdnnYSdVmQs6Xnla4JjoikDcHmMQYrCSNrI434C7BrA/EXf6Slad0kieY1BPsUKQahcWA5cj7otYTjKG/+/oplQU8oAMx1aKInkbAVL6BJ818ns82wVYHilLnlon4rIOTGeTIWHleB6mq4xfUAfTts1tXPh1YyubfwZGa3HO+K+WWgMeacHBuoOc1m7cr6HSPcvbvpnNhweAS9gdSqGSnoVA2cQAAAABJRU5ErkJggg=="
width="14"
/>
Go to Dashboard
</a>
[[ end ]]
[[ if .PanelURL]]
<a
href="[[ .PanelURL ]]"
class="button"
>
<img
alt=""
class="button-img"
height="14"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAE9SURBVHgBrVLNWcMwDH220/bjhEdIR2AC6ASMQEeAU6G9+FLycQojdAUmgE7ACGSEcEybRkj5cUKbnFp9X2JZ8nuypQecaUp+Kxf98BIeJ3cwNxqZDRB89mCTtXuZBvVGwBsCtiUrkYVS8RgHmzeVFB4Lwm9d9Y6XB/EbAhCK7atbbcRfuCjkRNwtt6fs4825RPyli4SkJNA40/wNFCm7cC6sdnnYSdVmQs6Xnla4JjoikDcHmMQYrCSNrI434C7BrA/EXf6Slad0kieY1BPsUKQahcWA5cj7otYTjKG/+/oplQU8oAMx1aKInkbAVL6BJ818ns82wVYHilLnlon4rIOTGeTIWHleB6mq4xfUAfTts1tXPh1YyubfwZGa3HO+K+WWgMeacHBuoOc1m7cr6HSPcvbvpnNhweAS9gdSqGSnoVA2cQAAAABJRU5ErkJggg=="
width="14"
/>
Go to Panel
</a>
[[ end ]]
[[ if gt (len .GeneratorURL) 0 ]]<a href="[[ .GeneratorURL ]]" class="button">Source</a>[[ end ]]
</td>
</tr>
<tr>
<td colspan="2">
<div style="height: 24px"></div>
<div style="background: #c7d0d9; height: 1px"></div>
<div style="height: 24px"></div>
</td>
</tr>
[[ end ]]
[[ if gt (len .Message) 0 ]]
<div style="white-space: pre-line;" align="left">[[ .Message ]]</span>
[[ else ]]
<style>
.button {
background: #f1f5f9;
border: 1px solid #c7d0d9;
border-radius: 2px;
color: #464c54;
display: inline-block;
font-size: 12px;
font-weight: bold;
margin: 0 10px 0 0;
padding: 5px 9px;
}
.value {
font-size: 14px;
padding-top: 24px;
}
.value-heading {
font-weight: bold;
}
.value-value {
padding-left: 8px;
}
.annotations {
font-size: 14px;
padding: 24px 0 12px 0;
}
.labels-heading {
font-size: 14px;
font-weight: bold;
vertical-align: top;
display: inline-block;
}
.annotations-heading {
font-weight: bold;
text-transform: capitalize;
}
.annotations-value {
padding-left: 8px;
}
.labels-list {
font-size: 14px;
vertical-align: top;
margin: 0;
display: inline-block;
padding-left: 8px;
}
.actions {
padding: 24px 0 12px 0;
}
.section-heading {
color: #2c3235;
font-size: 22px;
font-weight: bold;
padding: 0 0 32px 0;
}
.alert-label {
font-size: 16px;
font-weight: bold;
padding: 0 0 0 12px;
text-decoration: underline;
vertical-align: middle;
}
.status-tag {
color: #ffffff;
padding: 4px 8px;
text-align: center;
width: 68px
}
.status-firing {
background: #e02f44;
}
.status-resolved {
background: #464c54;
}
.button-img {
height: 14px;
margin: 0 5px 0 0;
vertical-align: sub;
width: 14px;
}
</style>
<table class="row">
<tr>
<td class="twelve">
<table>
[[ if gt (len .Alerts.Firing) 0 ]]
<tr>
<td colspan="2" class="section-heading">
Firing: [[ .Alerts.Firing | len ]] alert[[ if gt (len .Alerts.Firing) 1 ]]s[[ end ]][[ if gt (len .GroupLabels.SortedPairs) 1 ]] for
[[ range .GroupLabels.SortedPairs ]]
[[ .Name ]]=[[ .Value ]]
[[ end ]][[ end ]]
</td>
</tr>
[[ range .Alerts.Firing ]]
<tr>
<td
class="status-tag status-firing"
width="68"
>
Firing
</td>
<td class="alert-label">
[[ .Labels.alertname ]]
</td>
</tr>
[[ template "alert" . ]]
[[ end ]]
[[ end ]]
[[ if gt (len .Alerts.Resolved) 0 ]]
<tr>
<td colspan="2" class="section-heading">
Resolved: [[ .Alerts.Resolved | len ]] alert[[ if gt (len .Alerts.Resolved) 1 ]]s[[ end ]][[ if gt (len .GroupLabels.SortedPairs) 1 ]] for
[[ range .GroupLabels.SortedPairs ]]
[[ .Name ]]=[[ .Value ]]
[[ end ]][[ end ]]
</td>
</tr>
[[ range .Alerts.Resolved ]]
<tr>
<td
class="status-tag status-resolved"
width="68"
>
Resolved
</td>
<td class="alert-label">
[[ .Labels.alertname ]]
</td>
</tr>
[[ template "alert" . ]]
[[ end ]]
[[ end ]]
<tr>
<td colspan="2">
<a href="[[ .AlertPageUrl ]]" class="button">Go to alerts page</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
[[ end ]]
</div>
+122
View File
@@ -0,0 +1,122 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject "{{ .Title }}" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
<!-- Summary of the email contents, this will go in the email preview -->
<mj-include path="./partials/alerting/summary.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<!-- This is our grouping header, it says what grouping labels have been applied to this email -->
<mj-include path="./partials/alerting/grouping_labels.mjml" />
<!-- custom email message -->
<mj-raw>
{{ if .Message }}
</mj-raw>
<mj-wrapper background-color="#22252b" border="1px solid #2f3037" padding="0">
<mj-section padding="0">
<mj-column>
<mj-text align="left">
<mj-raw>
{{ range $line := (splitList "\n" .Message) }}
</mj-raw>
{{ $line }}<br />
<mj-raw>
{{ end }}
</mj-raw>
</mj-text>
</mj-column>
</mj-section>
</mj-wrapper>
<!-- end custom email message -->
<mj-raw>
{{ else }}
</mj-raw>
<!-- default template -->
<!-- Firing instances -->
<mj-raw>
{{ if .Alerts.Firing }}
</mj-raw>
<!-- Firing header -->
<mj-section padding="0">
<mj-column>
<mj-text padding="0">
<h3>🔥 {{ .Alerts.Firing | len }} firing instances</h3>
</mj-text>
</mj-column>
</mj-section>
<!-- Firing instances loop -->
<mj-raw>
{{ range .Alerts.Firing }}
</mj-raw>
<mj-wrapper background-color="#22252b" border="1px solid #2f3037" padding="0">
<mj-include path="./partials/alerting/firing_instance.mjml" />
<mj-include path="./partials/alerting/instance_details.mjml" />
</mj-wrapper>
<mj-section padding="10px" />
<!-- end Firing instances loop -->
<mj-raw>
{{ end }}
</mj-raw>
<!-- end Firing instances section -->
<mj-raw>
{{ end }}
</mj-raw>
<!-- Resolved instances -->
<mj-raw>
{{ if .Alerts.Resolved }}
</mj-raw>
<mj-section padding="0">
<mj-column>
<mj-text padding="0">
<h3>✅ {{ .Alerts.Resolved | len }} resolved instances</h3>
</mj-text>
</mj-column>
</mj-section>
<!-- Resolved instances loop -->
<mj-raw>
{{ range .Alerts.Resolved }}
</mj-raw>
<mj-wrapper background-color="#22252b" border="1px solid #2f3037" padding="0">
<mj-include path="./partials/alerting/resolved_instance.mjml" />
<mj-include path="./partials/alerting/instance_details.mjml" />
</mj-wrapper>
<mj-section padding="10px" />
<!-- end Resolved instances loop -->
<mj-raw>
{{ end }}
</mj-raw>
<!-- end Resolved instances -->
<mj-raw>
{{ end }}
</mj-raw>
<!-- end default template -->
<mj-raw>
{{ end }}
</mj-raw>
<mj-section padding-top="10px">
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
@@ -0,0 +1,23 @@
<mj-section padding="10px 0" border-bottom="1px solid #2f3037">
<mj-column vertical-align="middle">
<mj-button href="{{ .GeneratorURL }}" border="1px solid #970a1b" background-color="#392228" color="#f7919d" padding="0" inner-padding="5px 12px">
Firing
</mj-button>
</mj-column>
<mj-column vertical-align="middle">
<mj-text align="center" padding="0">
<strong>{{ .Labels.alertname }}</strong>
</mj-text>
</mj-column>
<mj-raw>
{{ if gt (len .GeneratorURL) 0 }}
</mj-raw>
<mj-column vertical-align="middle">
<mj-button href="{{ .GeneratorURL }}" padding="0" inner-padding="5px 12px">
View alert
</mj-button>
</mj-column>
<mj-raw>
{{ end }}
</mj-raw>
</mj-section>
@@ -0,0 +1,30 @@
<mj-section padding="0">
<mj-column>
<!-- we show this only when we're using the default grouping (grafana_folder, alertname) -->
<mj-raw>
{{ if eq (.GroupLabels.SortedPairs.Names | join ",") "alertname,grafana_folder" }}
</mj-raw>
<mj-text padding="0" align="left">
<h2>📁 {{ .GroupLabels.grafana_folder }} &rsaquo; {{ .GroupLabels.alertname }}</h2>
</mj-text>
<mj-raw>
{{ else }}
</mj-raw>
<!-- non-default grouping labels are just printed verbatim -->
<mj-text padding="0" align="left">
<h2>
📁 Grouped by&nbsp;
</h2>
<mj-raw>
{{ range .GroupLabels.SortedPairs }}
</mj-raw>
{{ .Name }}={{ .Value }}
<mj-raw>
{{ end }}
</mj-raw>
</mj-text>
<mj-raw>
{{ end }}
</mj-raw>
</mj-column>
</mj-section>
@@ -0,0 +1,195 @@
<!-- Image from external service -->
<mj-raw>
{{ if .ImageURL }}
</mj-raw>
<mj-section padding="0">
<mj-column border-bottom="1px solid #2f3037">
<mj-image href="{{ .ImageURL }}" src="{{ .ImageURL }}" padding="0" />
</mj-column>
</mj-section>
<mj-raw>
{{ end }}
</mj-raw>
<!-- Embedded Image -->
<mj-raw>
{{ if .EmbeddedImage }}
</mj-raw>
<mj-section padding="0">
<mj-column border-bottom="1px solid #2f3037">
<mj-image src="cid:{{ .EmbeddedImage }}" padding="0" />
</mj-column>
</mj-section>
<mj-raw>
{{ end }}
</mj-raw>
<mj-section padding="0" text-align="left">
<mj-column>
<!-- Summary -->
<mj-raw>
{{ if .Annotations.summary }}
</mj-raw>
<mj-text>
<strong>Summary</strong>
</mj-text>
<mj-text>
{{- .Annotations.summary -}}
</mj-text>
<mj-raw>
{{ end }}
</mj-raw>
<!-- Description -->
<mj-raw>
{{ if .Annotations.description }}
</mj-raw>
<mj-text>
<strong>Description</strong>
</mj-text>
<mj-text>
<mj-raw>
{{ range $line := (splitList "\n" .Annotations.description) }}
</mj-raw>
{{ $line }}<br />
<mj-raw>
{{ end }}
</mj-raw>
</mj-text>
<mj-raw>
{{ end }}
</mj-raw>
</mj-column>
</mj-section>
<!-- Values -->
<mj-raw>
{{ if .Values }}
</mj-raw>
<mj-section padding="0" text-align="left">
<mj-column>
<mj-text>
<strong>Values</strong>
</mj-text>
</mj-column>
</mj-section>
<mj-section padding="0 25px" text-align="left">
<mj-column padding="10px" background-color="#111217" border="1px solid #2f3037">
<mj-text>
<mj-raw>
{{ range $refID, $value := .Values }}
</mj-raw>
{{ $refID }}={{ $value }}&nbsp;
<mj-raw>
{{ end }}
</mj-raw>
</mj-text>
</mj-column>
</mj-section>
<mj-raw>
{{ end }}
</mj-raw>
<!-- Labels and annotations -->
<mj-section>
<mj-column>
<!-- Labels -->
<mj-raw>
{{ if .Labels.SortedPairs }}
</mj-raw>
<mj-text>
<strong>Labels</strong>
</mj-text>
<mj-table color="white">
<mj-raw>
{{ range .Labels.SortedPairs }}
</mj-raw>
<tr>
<td>
<strong>{{ .Name }}</strong>
</td>
<td>
{{ .Value }}
</td>
</tr>
<mj-raw>
{{ end }}
</mj-raw>
</mj-table>
<mj-raw>
{{ end }}
</mj-raw>
<!-- Annotations -->
<mj-raw>
{{ if .Annotations.SortedPairs }}
</mj-raw>
<mj-text>
<strong>Annotations</strong>
</mj-text>
<mj-table color="white">
<mj-raw>
{{ range .Annotations.SortedPairs }}
</mj-raw>
<tr>
<td>
<strong>{{ .Name }}</strong>
</td>
<td>
{{ .Value }}
</td>
</tr>
<mj-raw>
{{ end }}
</mj-raw>
</mj-table>
<mj-raw>
{{ end }}
</mj-raw>
</mj-column>
</mj-section>
<!-- actions -->
<mj-section text-align="left" border-top="1px solid #2f3037" padding="15px 0px">
<mj-raw>{{ if .SilenceURL }}</mj-raw>
<mj-column>
<mj-button align="center" vertical-align="middle" href="{{ .SilenceURL }}" padding="0" inner-padding="5px 12px">
Silence
</mj-button>
</mj-column>
<mj-raw>{{ end }}</mj-raw>
<mj-raw>{{ if .Annotations.runbook_url }}</mj-raw>
<mj-column>
<mj-button align="center" href="{{ .Annotations.runbook_url }}" padding="0" inner-padding="5px 12px">
View runbook
</mj-button>
</mj-column>
<mj-raw>{{ end }}</mj-raw>
<mj-raw>{{ if .DashboardURL }}</mj-raw>
<mj-column>
<mj-button align="center" href="{{ .DashboardURL }}" padding="0" inner-padding="5px 12px">
View dashboard
</mj-button>
</mj-column>
<mj-raw>{{ end }}</mj-raw>
<mj-raw>{{ if .PanelURL }}</mj-raw>
<mj-column>
<mj-button align="center" href="{{ .PanelURL }}" padding="0" inner-padding="5px 12px">
View panel
</mj-button>
</mj-column>
<mj-raw>{{ end }}</mj-raw>
</mj-section>
<!-- Observed -->
<mj-section border-top="1px solid #2f3037" padding="5px 0">
<mj-column>
<mj-text color="#91929e">
Observed <strong>{{ ago .StartsAt }}</strong> before this notification was delivered, at <strong>{{ .StartsAt }}</strong>
</mj-text>
</mj-column>
</mj-section>
@@ -0,0 +1,23 @@
<mj-section padding="10px 0" border-bottom="1px solid #2f3037">
<mj-column vertical-align="middle">
<mj-button border="1px solid #32632b" color="#a5d69e" background-color="#26322a" padding="0" inner-padding="5px 12px">
Resolved
</mj-button>
</mj-column>
<mj-column vertical-align="middle">
<mj-text align="center" padding="0">
<strong>{{ .Labels.alertname }}</strong>
</mj-text>
</mj-column>
<mj-raw>
{{ if gt (len .GeneratorURL) 0 }}
</mj-raw>
<mj-column vertical-align="middle">
<mj-button href="{{ .GeneratorURL }}" padding="0" inner-padding="5px 12px">
View alert
</mj-button>
</mj-column>
<mj-raw>
{{ end }}
</mj-raw>
</mj-section>
@@ -0,0 +1,28 @@
<mj-raw>
{{ $numberOfFiringInstance := (len .Alerts.Firing) }}
{{ $numberOfResolvedAlerts := (len .Alerts.Resolved) }}
</mj-raw>
<mj-preview>
<mj-raw>
{{ if $numberOfFiringInstance }}
</mj-raw>
<strong>{{ $numberOfFiringInstance }} firing</strong> alert {{ $numberOfFiringInstance| plural "instance" "instances" }}
<mj-raw>
{{ end }}
</mj-raw>
<mj-raw>
{{ if and $numberOfFiringInstance $numberOfResolvedAlerts }}
</mj-raw>
&nbsp;and&nbsp;
<mj-raw>
{{ end }}
</mj-raw>
<mj-raw>
{{ if $numberOfResolvedAlerts }}
</mj-raw>
<strong>{{ $numberOfResolvedAlerts }} resolved</strong> alert {{ $numberOfResolvedAlerts| plural "instance" "instances" }}
<mj-raw>
{{ end }}
</mj-raw>
</mj-preview>
@@ -0,0 +1,3 @@
{{> body }}
Sent by Grafana v[[.BuildVersion]] (c) [[now | date "2006"]] Grafana Labs
@@ -0,0 +1,5 @@
<mj-column background-color="transparent">
<mj-text align="center">
&copy; {{ now | date "2006" }} Grafana Labs. Sent by <a href="{{ .AppUrl }}">Grafana v{{ .BuildVersion }}</a>.
</mj-text>
</mj-column>
@@ -0,0 +1,10 @@
<mj-attributes>
<mj-text align="left" color="#FFF" line-height="1.5" />
<mj-button background-color="#3D71D9" rel="noopener" />
<mj-body background-color="#111217" />
</mj-attributes>
<mj-style inline="inline">
a {
color: #6E9FFF;
}
</mj-style>
@@ -0,0 +1,3 @@
<mj-column background-color="transparent">
<mj-image padding="0" width="200px" src="https://grafana.com/static/assets/img/logo_new_transparent_400x100.png" align="left" />
</mj-column>
-42
View File
@@ -1,42 +0,0 @@
[[Subject .Subject "Reset your Grafana password - [[.Name]]"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td>
<h4>Hi [[.Name]],</h4>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
<p>
Please click the following link to reset your password within <b>[[.EmailCodeValidHours]] hours</b>.
</p>
<p>
<a href="[[.AppUrl]]user/password/reset?code=[[.Code]]">[[.AppUrl]]user/password/reset?code=[[.Code]]</a>
</p>
<p>Not working? Try copying and pasting it to your browser.</p>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
+36
View File
@@ -0,0 +1,36 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject "Reset your Grafana password - {{.Name}}" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section background-color="#22252b" border="1px solid #2f3037">
<mj-column>
<mj-text>
<h2>Hi {{ .Name }},</h2>
</mj-text>
<mj-text>
Please click the following link to reset your password within <strong>{{ .EmailCodeValidHours }} hours</strong>.
</mj-text>
<mj-button href="{{ .AppUrl }}user/password/reset?code={{ .Code }}">
Reset Password
</mj-button>
<mj-text>
You can also copy and paste this link into your browser directly:
</mj-text>
<mj-text>
<a rel="noopener" href="{{ .AppUrl }}user/password/reset?code={{ .Code }}">{{ .AppUrl }}user/password/reset?code={{ .Code }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
-46
View File
@@ -1,46 +0,0 @@
[[Subject .Subject "Welcome to Grafana, please complete your sign up!"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td>
<h4 class="center">Complete the signup</h4>
</td>
<td class="expander"></td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
Copy and paste the email verification code:<br>
<span class="verification-code">[[.Code]]</span><br> in
the sign up form <strong>or</strong> use the link below.
</td>
<td class="expander"></td>
</tr>
<tr>
<td class="center">
<table class="better-button" align="center" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" class="better-button" bgcolor="#ff8f2b"><a rel="noopener noreferrer" href="[[.SignUpUrl]]" target="_blank">Complete Sign Up</a></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
+39
View File
@@ -0,0 +1,39 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject "Welcome to Grafana, please complete your sign up!" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section background-color="#22252b" border="1px solid #2f3037">
<mj-column>
<mj-text>
<h2>Complete the signup</h2>
</mj-text>
<mj-text>
Copy and paste the email verification code in the sign up form <strong>or</strong> use the link below.
</mj-text>
<mj-button background-color="transparent" border="1px solid #44474f" color="#ccccdd" font-size="22px" font-weight="bold">
{{ .Code }}
</mj-button>
<mj-button href="{{ .SignUpUrl }}">
Complete Sign Up
</mj-button>
<mj-text>
You can also copy and paste this link into your browser directly:
</mj-text>
<mj-text>
<a rel="noopener" href="{{ .LinkUrl }}">{{ .SignUpUrl }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
-48
View File
@@ -1,48 +0,0 @@
[[Subject .Subject "Welcome to Grafana"]]
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td>
<h4>Hi [[.Name]],</h4>
</td>
<td class="expander"></td>
</tr>
<tr>
<td>
Welcome! Ready to start building some beautiful metric and analytic dashboards?
</td>
</tr>
</table>
</td>
</tr>
</table>
<table class="row">
<tr>
<td class="wrapper last">
<table class="twelve columns">
<tr>
<td class="center">
<p>
If you are new to Grafana, refer to the <a href="https://grafana.com/docs/grafana/latest/getting-started/getting-started/">Getting started with Grafana</a> guide.
</p>
</td>
<td class="expander"></td>
</tr>
<tr>
<td>
Thank you for joining our community.
<br />
<p>The Grafana Team</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
+40
View File
@@ -0,0 +1,40 @@
<mjml>
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject "Welcome to Grafana" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section background-color="#22252b" border="1px solid #2f3037">
<mj-column>
<mj-text>
<h2>Hi {{ .Name }},</h2>
</mj-text>
<mj-text>
Welcome! Ready to start building some beautiful metric and analytic dashboards?
</mj-text>
<mj-text>
If you are new to Grafana, refer to the <a href="https://grafana.com/docs/grafana/latest/getting-started/getting-started/">Getting started with Grafana</a>
guide.
</mj-text>
<mj-button href="https://grafana.com/docs/grafana/latest/getting-started/getting-started/">
Check out our getting started guide
</mj-button>
<mj-text>
Thank you for joining our community.
</mj-text>
<mj-text>
The Grafana Team
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>
+15 -3
View File
@@ -256,9 +256,7 @@ require (
github.com/grafana/codejen v0.0.3
github.com/grafana/dskit v0.0.0-20211011144203-3a88ec0b675f
github.com/jmoiron/sqlx v1.3.5
github.com/kr/pretty v0.3.0
github.com/matryer/is v1.4.0
github.com/parca-dev/parca v0.12.1
github.com/urfave/cli v1.22.9
go.etcd.io/etcd/api/v3 v3.5.4
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.32.0
@@ -271,11 +269,16 @@ require (
require (
cloud.google.com/go v0.102.0 // indirect
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/armon/go-metrics v0.3.10 // indirect
github.com/bmatcuk/doublestar v1.1.1 // indirect
github.com/buildkite/yaml v2.1.0+incompatible // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/drone-runners/drone-runner-docker v1.8.2 // indirect
github.com/drone/drone-go v1.7.1 // indirect
github.com/drone/envsubst v1.0.3 // indirect
@@ -287,15 +290,22 @@ require (
github.com/gosimple/unidecode v1.0.1 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/memberlist v0.4.0 // indirect
github.com/huandu/xstrings v1.3.1 // indirect
github.com/invopop/yaml v0.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-ieproxy v0.0.3 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/parca-dev/parca v0.12.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/segmentio/asm v1.1.4 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect
)
@@ -305,6 +315,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.22.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.2
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
github.com/RoaringBitmap/roaring v0.9.4 // indirect
@@ -321,6 +332,7 @@ require (
github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/docker/docker v20.10.21+incompatible
github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
+15
View File
@@ -234,11 +234,16 @@ github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnl
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig v2.16.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Masterminds/squirrel v0.0.0-20161115235646-20f192218cf5/go.mod h1:xnKTFzjGUiZtiOagBsfnvomW+nJg2usB1ZpordQWqNM=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -574,6 +579,7 @@ github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoT
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw=
github.com/containerd/containerd v1.6.8 h1:h4dOFDwzHmqFEP754PgfgTeVXFnLiRc6kiqC7tplDJs=
github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@@ -746,6 +752,7 @@ github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
@@ -1507,6 +1514,8 @@ github.com/hetznercloud/hcloud-go v1.33.2 h1:ptWKVYLW7YtjXzsqTFKFxwpVo3iM9UMkVPB
github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -1865,6 +1874,7 @@ github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -2003,6 +2013,7 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -2265,6 +2276,7 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v3.21.6+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
@@ -2305,6 +2317,7 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52
github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -2667,6 +2680,7 @@ golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -3472,6 +3486,7 @@ k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+1 -2
View File
@@ -7,7 +7,7 @@ module.exports = {
verbose: false,
testEnvironment: 'jsdom',
transform: {
'^.+\\.(ts|tsx|js|jsx)$': require.resolve('ts-jest'),
'^.+\\.(ts|tsx|js|jsx)$': [require.resolve('ts-jest'), { isolatedModules: true }],
},
transformIgnorePatterns: [
'node_modules/(?!(ol)/)', // <- exclude the open layers library
@@ -22,7 +22,6 @@ module.exports = {
setupFilesAfterEnv: ['./public/test/setupTests.ts'],
snapshotSerializers: ['enzyme-to-json/serializer'],
globals: {
'ts-jest': { isolatedModules: true },
__webpack_public_path__: '', // empty string
},
moduleNameMapper: {
+2 -9
View File
@@ -21,8 +21,6 @@ import (
"github.com/grafana/grafana/pkg/kindsys"
)
const sep = string(filepath.Separator)
func main() {
if len(os.Args) > 1 {
fmt.Fprintf(os.Stderr, "plugin thema code generator does not currently accept any arguments\n, got %q", os.Args)
@@ -37,16 +35,11 @@ func main() {
// All the jennies that comprise the core kinds generator pipeline
coreKindsGen.Append(
codegen.GoTypesJenny(kindsys.GoCoreKindParentPath, nil),
codegen.LatestJenny(kindsys.GoCoreKindParentPath, codegen.GoTypesJenny{}),
codegen.CoreStructuredKindJenny(kindsys.GoCoreKindParentPath, nil),
codegen.RawKindJenny(kindsys.GoCoreKindParentPath, nil),
codegen.BaseCoreRegistryJenny(filepath.Join("pkg", "registry", "corekind"), kindsys.GoCoreKindParentPath),
codegen.TSTypesJenny(kindsys.TSCoreKindParentPath, &codegen.TSTypesGeneratorConfig{
GenDirName: func(decl *codegen.DeclForGen) string {
// FIXME this hardcodes always generating to experimental dir. OK for now, but need generator fanout
return filepath.Join(decl.Meta.Common().MachineName, "x")
},
}),
codegen.LatestMajorsOrXJenny(kindsys.TSCoreKindParentPath, codegen.TSTypesJenny{}),
codegen.TSVeneerIndexJenny(filepath.Join("packages", "grafana-schema", "src")),
)
+1 -1
View File
@@ -1,4 +1,4 @@
{
"stable": "9.2.5",
"stable": "9.2.6",
"testing": "9.3.0-beta1"
}
+6 -6
View File
@@ -125,7 +125,7 @@
"@types/gtag.js": "^0.0.12",
"@types/history": "4.7.11",
"@types/hoist-non-react-statics": "3.3.1",
"@types/jest": "28.1.6",
"@types/jest": "29.2.3",
"@types/jquery": "3.5.14",
"@types/js-yaml": "^4.0.5",
"@types/jsurl": "^1.2.28",
@@ -165,7 +165,7 @@
"@typescript-eslint/parser": "5.42.0",
"@wojtekmaj/enzyme-adapter-react-17": "0.7.0",
"autoprefixer": "10.4.13",
"babel-jest": "28.1.3",
"babel-jest": "29.3.1",
"babel-loader": "9.1.0",
"babel-plugin-angularjs-annotate": "0.10.0",
"babel-plugin-macros": "3.1.0",
@@ -195,13 +195,13 @@
"http-server": "14.1.1",
"husky": "8.0.1",
"i18next-parser": "6.6.0",
"jest": "28.1.3",
"jest": "29.3.1",
"jest-canvas-mock": "2.4.0",
"jest-date-mock": "1.0.8",
"jest-environment-jsdom": "28.1.3",
"jest-environment-jsdom": "29.3.1",
"jest-fail-on-console": "3.0.2",
"jest-junit": "14.0.1",
"jest-matcher-utils": "28.1.3",
"jest-matcher-utils": "29.3.1",
"lerna": "5.5.4",
"lint-staged": "13.0.3",
"mini-css-extract-plugin": "2.6.1",
@@ -230,7 +230,7 @@
"stylelint-config-sass-guidelines": "9.0.1",
"terser-webpack-plugin": "5.3.6",
"testing-library-selector": "0.2.1",
"ts-jest": "28.0.7",
"ts-jest": "29.0.3",
"ts-loader": "9.3.1",
"ts-node": "10.9.1",
"typescript": "4.8.4",
+1 -1
View File
@@ -66,7 +66,7 @@
"@testing-library/react-hooks": "8.0.1",
"@testing-library/user-event": "14.4.3",
"@types/history": "4.7.11",
"@types/jest": "28.1.6",
"@types/jest": "29.2.3",
"@types/jquery": "3.5.14",
"@types/lodash": "4.14.187",
"@types/marked": "4.0.7",
@@ -40,14 +40,14 @@ describe('Array DataFrame', () => {
test('Should convert an array of objects to a dataframe', () => {
expect(toDataFrameDTO(frame)).toMatchInlineSnapshot(`
Object {
"fields": Array [
Object {
"config": Object {},
{
"fields": [
{
"config": {},
"labels": undefined,
"name": "name",
"type": "string",
"values": Array [
"values": [
"first",
"second",
"third",
@@ -55,14 +55,14 @@ describe('Array DataFrame', () => {
"5th (Null)",
],
},
Object {
"config": Object {
{
"config": {
"unit": "kwh",
},
"labels": undefined,
"name": "value",
"type": "number",
"values": Array [
"values": [
1,
2,
3,
@@ -70,12 +70,12 @@ describe('Array DataFrame', () => {
null,
],
},
Object {
"config": Object {},
{
"config": {},
"labels": undefined,
"name": "time",
"type": "time",
"values": Array [
"values": [
123,
456,
789,
@@ -83,12 +83,12 @@ describe('Array DataFrame', () => {
1100,
],
},
Object {
"config": Object {},
{
"config": {},
"labels": undefined,
"name": "phantom",
"type": "string",
"values": Array [
"values": [
"🦥",
"🦥",
"🦥",
@@ -29,50 +29,50 @@ describe('DataFrame JSON', () => {
const frame = dataFrameFromJSON(json);
expect(frame).toMatchInlineSnapshot(`
Object {
"fields": Array [
Object {
"config": Object {},
"entities": Object {},
{
"fields": [
{
"config": {},
"entities": {},
"name": "time",
"type": "time",
"values": Array [
"values": [
100,
200,
300,
],
},
Object {
"config": Object {},
"entities": Object {
"Inf": Array [
{
"config": {},
"entities": {
"Inf": [
1,
],
"NaN": Array [
"NaN": [
0,
],
"Undef": Array [
"Undef": [
2,
],
},
"name": "name",
"type": "string",
"values": Array [
"values": [
NaN,
Infinity,
undefined,
],
},
Object {
"config": Object {},
"entities": Object {
"NegInf": Array [
{
"config": {},
"entities": {
"NegInf": [
2,
],
},
"name": "value",
"type": "number",
"values": Array [
"values": [
1,
2,
-Infinity,
@@ -106,26 +106,26 @@ describe('DataFrame JSON', () => {
const frame = dataFrameFromJSON(json);
expect(frame).toMatchInlineSnapshot(`
Object {
"fields": Array [
Object {
"config": Object {},
"entities": Object {},
{
"fields": [
{
"config": {},
"entities": {},
"name": "time",
"type": "time",
"values": Array [
"values": [
100,
200,
300,
400,
],
},
Object {
"config": Object {},
"entities": Object {},
{
"config": {},
"entities": {},
"name": "value",
"type": "string",
"values": Array [
"values": [
"bar",
"foo",
"baz",
@@ -199,16 +199,16 @@ describe('toDataFrame', () => {
};
const dataFrame = toDataFrame(msg);
expect(dataFrame.fields.map((f) => ({ [f.name]: f.values.toArray() }))).toMatchInlineSnapshot(`
Array [
Object {
"First": Array [
[
{
"First": [
"2019-02-15",
"2019-03-15",
"2019-04-15",
],
},
Object {
"Second": Array [
{
"Second": [
3,
9,
16,
@@ -186,29 +186,29 @@ describe('applyFieldOverrides', () => {
});
expect(withOverrides[0].fields[0].state!.scopedVars).toMatchInlineSnapshot(`
Object {
"__field": Object {
"text": "Field",
"value": Object {},
},
"__series": Object {
"text": "Series",
"value": Object {
"name": "A",
},
},
}
`);
{
"__field": {
"text": "Field",
"value": {},
},
"__series": {
"text": "Series",
"value": {
"name": "A",
},
},
}
`);
expect(withOverrides[1].fields[0].state!.scopedVars).toMatchInlineSnapshot(`
Object {
"__field": Object {
{
"__field": {
"text": "Field",
"value": Object {},
"value": {},
},
"__series": Object {
"__series": {
"text": "Series",
"value": Object {
"value": {
"name": "B",
},
},
@@ -384,8 +384,8 @@ describe('setFieldConfigDefaults', () => {
setFieldConfigDefaults(dsFieldConfig, panelFieldConfig, context);
expect(dsFieldConfig).toMatchInlineSnapshot(`
Object {
"custom": Object {},
{
"custom": {},
"decimals": 2,
"max": 100,
"min": 0,
@@ -419,8 +419,8 @@ describe('setFieldConfigDefaults', () => {
setFieldConfigDefaults(dsFieldConfig, panelFieldConfig, context);
expect(dsFieldConfig).toMatchInlineSnapshot(`
Object {
"custom": Object {
{
"custom": {
"property1": 10,
"property2": 10,
},
@@ -208,12 +208,12 @@ describe('calculateField transformer w/ timeseries', () => {
const filtered = data[0];
const rows = new DataFrameView(filtered).toArray();
expect(rows).toMatchInlineSnapshot(`
Array [
Object {
[
{
"E * 1": 1,
"TheTime": 1000,
},
Object {
{
"E * 1": 0,
"TheTime": 2000,
},
@@ -267,12 +267,12 @@ describe('calculateField transformer w/ timeseries', () => {
const filtered = data[0];
const rows = new DataFrameView(filtered).toArray();
expect(rows).toMatchInlineSnapshot(`
Array [
Object {
[
{
"Test": 6,
"TheTime": 1000,
},
Object {
{
"Test": 105,
"TheTime": 2000,
},
@@ -25,28 +25,28 @@ describe('Concat Transformer', () => {
const frame = concatenateFields([simpleABC, simpleXYZ], { frameNameMode: ConcatenateFrameNameMode.Drop });
expect(frame.length).toBe(3);
expect(frame.fields.map((f) => ({ name: f.name, labels: f.labels }))).toMatchInlineSnapshot(`
Array [
Object {
[
{
"labels": undefined,
"name": "A",
},
Object {
{
"labels": undefined,
"name": "B",
},
Object {
{
"labels": undefined,
"name": "C",
},
Object {
{
"labels": undefined,
"name": "X",
},
Object {
{
"labels": undefined,
"name": "Y",
},
Object {
{
"labels": undefined,
"name": "Z",
},
@@ -58,28 +58,28 @@ describe('Concat Transformer', () => {
const frame = concatenateFields([simpleABC, simpleXYZ], { frameNameMode: ConcatenateFrameNameMode.FieldName });
expect(frame.length).toBe(3);
expect(frame.fields.map((f) => ({ name: f.name, labels: f.labels }))).toMatchInlineSnapshot(`
Array [
Object {
[
{
"labels": undefined,
"name": "ABC · A",
},
Object {
{
"labels": undefined,
"name": "ABC · B",
},
Object {
{
"labels": undefined,
"name": "ABC · C",
},
Object {
{
"labels": undefined,
"name": "XYZ · X",
},
Object {
{
"labels": undefined,
"name": "XYZ · Y",
},
Object {
{
"labels": undefined,
"name": "XYZ · Z",
},
@@ -94,39 +94,39 @@ describe('Concat Transformer', () => {
});
expect(frame.length).toBe(3);
expect(frame.fields.map((f) => ({ name: f.name, labels: f.labels }))).toMatchInlineSnapshot(`
Array [
Object {
"labels": Object {
[
{
"labels": {
"sensor": "ABC",
},
"name": "A",
},
Object {
"labels": Object {
{
"labels": {
"sensor": "ABC",
},
"name": "B",
},
Object {
"labels": Object {
{
"labels": {
"sensor": "ABC",
},
"name": "C",
},
Object {
"labels": Object {
{
"labels": {
"sensor": "XYZ",
},
"name": "X",
},
Object {
"labels": Object {
{
"labels": {
"sensor": "XYZ",
},
"name": "Y",
},
Object {
"labels": Object {
{
"labels": {
"sensor": "XYZ",
},
"name": "Z",
@@ -51,66 +51,66 @@ describe('ensureColumns transformer', () => {
const frame = filtered[0];
expect(frame.fields.length).toEqual(5);
expect(filtered[0]).toMatchInlineSnapshot(`
Object {
"fields": Array [
Object {
"config": Object {},
{
"fields": [
{
"config": {},
"name": "TheTime",
"state": Object {},
"state": {},
"type": "time",
"values": Array [
"values": [
1000,
2000,
],
},
Object {
"config": Object {},
"labels": Object {},
{
"config": {},
"labels": {},
"name": "A",
"state": Object {},
"state": {},
"type": "number",
"values": Array [
"values": [
1,
100,
],
},
Object {
"config": Object {},
"labels": Object {},
{
"config": {},
"labels": {},
"name": "B",
"state": Object {},
"state": {},
"type": "number",
"values": Array [
"values": [
2,
200,
],
},
Object {
"config": Object {},
"labels": Object {},
{
"config": {},
"labels": {},
"name": "C",
"state": Object {},
"state": {},
"type": "number",
"values": Array [
"values": [
3,
300,
],
},
Object {
"config": Object {},
"labels": Object {},
{
"config": {},
"labels": {},
"name": "D",
"state": Object {},
"state": {},
"type": "string",
"values": Array [
"values": [
"first",
"second",
],
},
],
"length": 2,
"meta": Object {
"transformations": Array [
"meta": {
"transformations": [
"ensureColumns",
],
},
@@ -128,34 +128,34 @@ describe('Grouping to Matrix', () => {
const processed = received[0];
expect(processed[0].fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {},
"name": "Row\\\\Column",
[
{
"config": {},
"name": "Row\\Column",
"type": "string",
"values": Array [
"values": [
"R1",
"R2",
],
},
Object {
"config": Object {
{
"config": {
"units": "celsius",
},
"name": "C1",
"type": "number",
"values": Array [
"values": [
1,
4,
],
},
Object {
"config": Object {
{
"config": {
"units": "celsius",
},
"name": "C2",
"type": "number",
"values": Array [
"values": [
5,
"",
],
@@ -30,13 +30,13 @@ describe('histogram frames frames', () => {
config: f.config,
}))
).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {
[
{
"config": {
"unit": "mph",
},
"name": "BucketMin",
"values": Array [
"values": [
1,
2,
3,
@@ -48,12 +48,12 @@ describe('histogram frames frames', () => {
9,
],
},
Object {
"config": Object {
{
"config": {
"unit": "mph",
},
"name": "BucketMax",
"values": Array [
"values": [
2,
3,
4,
@@ -65,12 +65,12 @@ describe('histogram frames frames', () => {
10,
],
},
Object {
"config": Object {
{
"config": {
"unit": undefined,
},
"name": "A",
"values": Array [
"values": [
1,
1,
1,
@@ -82,12 +82,12 @@ describe('histogram frames frames', () => {
0,
],
},
Object {
"config": Object {
{
"config": {
"unit": undefined,
},
"name": "B",
"values": Array [
"values": [
0,
0,
1,
@@ -99,12 +99,12 @@ describe('histogram frames frames', () => {
0,
],
},
Object {
"config": Object {
{
"config": {
"unit": undefined,
},
"name": "C",
"values": Array [
"values": [
0,
0,
0,
@@ -116,12 +116,12 @@ describe('histogram frames frames', () => {
1,
],
},
Object {
"config": Object {
{
"config": {
"unit": undefined,
},
"name": "C",
"values": Array [
"values": [
0,
0,
0,
@@ -143,10 +143,10 @@ describe('histogram frames frames', () => {
values: f.values.toArray(),
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "BucketMin",
"values": Array [
"values": [
1,
2,
3,
@@ -158,9 +158,9 @@ describe('histogram frames frames', () => {
9,
],
},
Object {
{
"name": "BucketMax",
"values": Array [
"values": [
2,
3,
4,
@@ -172,9 +172,9 @@ describe('histogram frames frames', () => {
10,
],
},
Object {
{
"name": "Count",
"values": Array [
"values": [
1,
1,
2,
File diff suppressed because it is too large Load Diff
@@ -36,42 +36,42 @@ describe('align frames', () => {
values: f.values.toArray(),
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"values": Array [
"values": [
1000,
1500,
2000,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
1,
undefined,
100,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
2,
20,
200,
],
},
Object {
{
"name": "B",
"values": Array [
"values": [
3,
30,
300,
],
},
Object {
{
"name": "C",
"values": Array [
"values": [
"first",
"second",
"third",
@@ -89,38 +89,38 @@ describe('align frames', () => {
values: f.values.toArray(),
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"values": Array [
"values": [
1000,
2000,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
1,
100,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
2,
200,
],
},
Object {
{
"name": "B",
"values": Array [
"values": [
3,
300,
],
},
Object {
{
"name": "C",
"values": Array [
"values": [
"first",
"third",
],
@@ -154,44 +154,44 @@ describe('align frames', () => {
state: f.state,
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"state": Object {
"origin": Object {
"state": {
"origin": {
"fieldIndex": 0,
"frameIndex": 0,
},
},
"values": Array [
"values": [
1000,
1500,
2000,
],
},
Object {
{
"name": "A1",
"state": Object {
"origin": Object {
"state": {
"origin": {
"fieldIndex": 1,
"frameIndex": 0,
},
},
"values": Array [
"values": [
1,
15,
2,
],
},
Object {
{
"name": "A2",
"state": Object {
"origin": Object {
"state": {
"origin": {
"fieldIndex": 1,
"frameIndex": 1,
},
},
"values": Array [
"values": [
1,
undefined,
2,
@@ -208,20 +208,20 @@ describe('align frames', () => {
state: f.state,
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"state": Object {
"origin": Object {
"state": {
"origin": {
"fieldIndex": 0,
"frameIndex": 0,
},
},
},
Object {
{
"name": "A1",
"state": Object {
"origin": Object {
"state": {
"origin": {
"fieldIndex": 1,
"frameIndex": 0,
},
@@ -246,18 +246,18 @@ describe('align frames', () => {
values: f.values.toArray(),
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"values": Array [
"values": [
1500,
2000,
6000,
],
},
Object {
{
"name": "A1",
"values": Array [
"values": [
15,
22,
1,
@@ -293,24 +293,24 @@ describe('align frames', () => {
values: f.values.toArray(),
}))
).toMatchInlineSnapshot(`
Array [
Object {
[
{
"name": "TheTime",
"values": Array [
"values": [
1000,
2000,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
1,
100,
],
},
Object {
{
"name": "A",
"values": Array [
"values": [
200,
undefined,
],
@@ -28,20 +28,20 @@ describe('Labels as Columns', () => {
await expect(transformDataFrame([cfg], [source])).toEmitValuesWith((received) => {
const data = received[0];
expect(toSimpleObject(data[0])).toMatchInlineSnapshot(`
Object {
"Value": Array [
{
"Value": [
1,
2,
],
"feelsLike": Array [
"feelsLike": [
"ok",
"ok",
],
"location": Array [
"location": [
"inside",
"inside",
],
"time": Array [
"time": [
1000,
2000,
],
@@ -119,27 +119,27 @@ describe('Labels as Columns', () => {
expect(data.length).toEqual(2);
expect(toSimpleObject(data[0])).toMatchInlineSnapshot(`
Object {
"location": Array [
{
"location": [
"inside",
],
"temp": Array [
"temp": [
1,
],
"time": Array [
"time": [
1000,
],
}
`);
expect(toSimpleObject(data[1])).toMatchInlineSnapshot(`
Object {
"location": Array [
{
"location": [
"outside",
],
"temp": Array [
"temp": [
-1,
],
"time": Array [
"time": [
2000,
],
}
@@ -196,33 +196,33 @@ describe('Labels as Columns', () => {
await expect(transformDataFrame([cfg], [source])).toEmitValuesWith((received) => {
expect(received[0][0].fields.map((f) => ({ [f.name]: f.values.toArray() }))).toMatchInlineSnapshot(`
Array [
Object {
"time": Array [
[
{
"time": [
1000,
2000,
],
},
Object {
"a": Array [
{
"a": [
1,
3,
],
},
Object {
"b": Array [
{
"b": [
2,
4,
],
},
Object {
"foo": Array [
{
"foo": [
"thing",
"thing",
],
},
Object {
"bar": Array [
{
"bar": [
"thing",
"thing",
],
@@ -285,42 +285,42 @@ describe('Labels as Columns', () => {
expect(
received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values.toArray() })) }))
).toMatchInlineSnapshot(`
Array [
Object {
"fields": Array [
Object {
"label": Array [
[
{
"fields": [
{
"label": [
"foo",
"bar",
"zaz",
],
},
Object {
"value": Array [
{
"value": [
"thing",
"a",
"xyz",
],
},
],
"name": "a {bar=\\"a\\", foo=\\"thing\\", zaz=\\"xyz\\"}",
"name": "a {bar="a", foo="thing", zaz="xyz"}",
},
Object {
"fields": Array [
Object {
"label": Array [
{
"fields": [
{
"label": [
"foo",
"bar",
],
},
Object {
"value": Array [
{
"value": [
"thing",
"b",
],
},
],
"name": "b {bar=\\"b\\", foo=\\"thing\\"}",
"name": "b {bar="b", foo="thing"}",
},
]
`);
@@ -349,40 +349,40 @@ describe('Labels as Columns', () => {
expect(
received[0].map((f) => ({ name: f.name, fields: f.fields.map((v) => ({ [v.name]: v.values.toArray() })) }))
).toMatchInlineSnapshot(`
Array [
Object {
"fields": Array [
Object {
"label": Array [
[
{
"fields": [
{
"label": [
"zaz",
"bar",
],
},
Object {
"value": Array [
{
"value": [
"xyz",
"a",
],
},
],
"name": "a {bar=\\"a\\", foo=\\"thing\\", zaz=\\"xyz\\"}",
"name": "a {bar="a", foo="thing", zaz="xyz"}",
},
Object {
"fields": Array [
Object {
"label": Array [
{
"fields": [
{
"label": [
"zaz",
"bar",
],
},
Object {
"value": Array [
{
"value": [
undefined,
"b",
],
},
],
"name": "b {bar=\\"b\\", foo=\\"thing\\"}",
"name": "b {bar="b", foo="thing"}",
},
]
`);
@@ -264,12 +264,12 @@ describe('Reducer Transformer', () => {
const view0 = new DataFrameView<any>(frames[0]);
const view1 = new DataFrameView<any>(frames[1]);
expect({ ...view0.get(0) }).toMatchInlineSnapshot(`
Object {
{
"temperature": 6,
}
`);
expect({ ...view1.get(0) }).toMatchInlineSnapshot(`
Object {
{
"humidity": 10000.6,
"temperature": 6,
}
@@ -398,45 +398,45 @@ describe('Reducer Transformer', () => {
expect(processed.length).toEqual(1);
expect(processed[0].fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {},
[
{
"config": {},
"name": "Field",
"type": "string",
"values": Array [
"values": [
"value",
"value",
"value",
"value",
],
},
Object {
"config": Object {},
{
"config": {},
"name": "state",
"type": "string",
"values": Array [
"values": [
"CA",
"NY",
"CA",
,
],
},
Object {
"config": Object {},
{
"config": {},
"name": "country",
"type": "string",
"values": Array [
"values": [
,
,
"USA",
"USA",
],
},
Object {
"config": Object {},
{
"config": {},
"name": "Max",
"type": "number",
"values": Array [
"values": [
6,
6,
6,
@@ -42,35 +42,35 @@ describe('Rename By Regex Transformer', () => {
const data = received[0];
const frame = data[0];
expect(frame.fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {
[
{
"config": {
"name": "Time",
},
"name": "Time",
"state": Object {
"state": {
"displayName": "Time",
"multipleFrames": false,
},
"type": "time",
"values": Array [
"values": [
3000,
4000,
5000,
6000,
],
},
Object {
"config": Object {
{
"config": {
"displayName": "web-01",
},
"name": "Value",
"state": Object {
"state": {
"displayName": "web-01",
"multipleFrames": false,
},
"type": "number",
"values": Array [
"values": [
10000.3,
10000.4,
10000.5,
@@ -94,36 +94,36 @@ describe('Rename By Regex Transformer', () => {
const data = received[0];
const frame = data[0];
expect(frame.fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {
[
{
"config": {
"displayName": "TimE",
"name": "Time",
},
"name": "Time",
"state": Object {
"state": {
"displayName": "TimE",
"multipleFrames": false,
},
"type": "time",
"values": Array [
"values": [
3000,
4000,
5000,
6000,
],
},
Object {
"config": Object {
{
"config": {
"displayName": "wEb-01.ExamplE.com",
},
"name": "Value",
"state": Object {
"state": {
"displayName": "wEb-01.ExamplE.com",
"multipleFrames": false,
},
"type": "number",
"values": Array [
"values": [
10000.3,
10000.4,
10000.5,
@@ -147,35 +147,35 @@ describe('Rename By Regex Transformer', () => {
const data = received[0];
const frame = data[0];
expect(frame.fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {
[
{
"config": {
"name": "Time",
},
"name": "Time",
"state": Object {
"state": {
"displayName": "Time",
"multipleFrames": false,
},
"type": "time",
"values": Array [
"values": [
3000,
4000,
5000,
6000,
],
},
Object {
"config": Object {
{
"config": {
"displayName": "web-01.example.com",
},
"name": "Value",
"state": Object {
"state": {
"displayName": "web-01.example.com",
"multipleFrames": false,
},
"type": "number",
"values": Array [
"values": [
10000.3,
10000.4,
10000.5,
@@ -199,35 +199,35 @@ describe('Rename By Regex Transformer', () => {
const data = received[0];
const frame = data[0];
expect(frame.fields).toMatchInlineSnapshot(`
Array [
Object {
"config": Object {
[
{
"config": {
"name": "Time",
},
"name": "Time",
"state": Object {
"state": {
"displayName": "Time",
"multipleFrames": false,
},
"type": "time",
"values": Array [
"values": [
3000,
4000,
5000,
6000,
],
},
Object {
"config": Object {
{
"config": {
"displayName": "web-01.example.com",
},
"name": "Value",
"state": Object {
"state": {
"displayName": "web-01.example.com",
"multipleFrames": false,
},
"type": "number",
"values": Array [
"values": [
10000.3,
10000.4,
10000.5,

Some files were not shown because too many files have changed in this diff Show More