From 5d11def03320b2a4ff2a6c34755c6105bce5bdc6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:52:09 +0300 Subject: [PATCH 01/24] Update dependency @babel/preset-typescript to v7.22.5 (#69832) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 316 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 307 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index a53a4281e39..97c6ea09e58 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@babel/plugin-transform-typescript": "7.22.3", "@babel/preset-env": "7.22.4", "@babel/preset-react": "7.22.3", - "@babel/preset-typescript": "7.21.5", + "@babel/preset-typescript": "7.22.5", "@babel/runtime": "7.22.3", "@betterer/betterer": "5.4.0", "@betterer/cli": "5.4.0", diff --git a/yarn.lock b/yarn.lock index ac5bf05dc0b..1cc8f33f222 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,6 +42,15 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/code-frame@npm:7.22.5" + dependencies: + "@babel/highlight": ^7.22.5 + checksum: cfe804f518f53faaf9a1d3e0f9f74127ab9a004912c3a16fda07fb6a633393ecb9918a053cb71804204c1b7ec3d49e1699604715e2cfb0c9f7bc4933d324ebb6 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.21.4, @babel/compat-data@npm:^7.22.0, @babel/compat-data@npm:^7.22.3": version: 7.22.3 resolution: "@babel/compat-data@npm:7.22.3" @@ -119,6 +128,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/generator@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + "@jridgewell/gen-mapping": ^0.3.2 + "@jridgewell/trace-mapping": ^0.3.17 + jsesc: ^2.5.1 + checksum: efa64da70ca88fe69f05520cf5feed6eba6d30a85d32237671488cc355fdc379fe2c3246382a861d49574c4c2f82a317584f8811e95eb024e365faff3232b49d + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-annotate-as-pure@npm:7.18.6" @@ -128,6 +149,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + languageName: node + linkType: hard + "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.18.6": version: 7.18.9 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.18.9" @@ -172,6 +202,25 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-create-class-features-plugin@npm:7.22.5" + dependencies: + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + semver: ^6.3.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: f1e91deae06dbee6dd956c0346bca600adfbc7955427795d9d8825f0439a3c3290c789ba2b4a02a1cdf6c1a1bd163dfa16d3d5e96b02a8efb639d2a774e88ed9 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.1": version: 7.22.1 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.1" @@ -208,6 +257,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-environment-visitor@npm:7.22.5" + checksum: 248532077d732a34cd0844eb7b078ff917c3a8ec81a7f133593f71a860a582f05b60f818dc5049c2212e5baa12289c27889a4b81d56ef409b4863db49646c4b1 + languageName: node + linkType: hard + "@babel/helper-explode-assignable-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-explode-assignable-expression@npm:7.18.6" @@ -227,6 +283,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-function-name@npm:7.22.5" + dependencies: + "@babel/template": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: 6b1f6ce1b1f4e513bf2c8385a557ea0dd7fa37971b9002ad19268ca4384bbe90c09681fe4c076013f33deabc63a53b341ed91e792de741b4b35e01c00238177a + languageName: node + linkType: hard + "@babel/helper-hoist-variables@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-hoist-variables@npm:7.18.6" @@ -236,6 +302,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.0.0, @babel/helper-member-expression-to-functions@npm:^7.22.0": version: 7.22.3 resolution: "@babel/helper-member-expression-to-functions@npm:7.22.3" @@ -245,6 +320,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-member-expression-to-functions@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 4bd5791529c280c00743e8bdc669ef0d4cd1620d6e3d35e0d42b862f8262bc2364973e5968007f960780344c539a4b9cf92ab41f5b4f94560a9620f536de2a39 + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-module-imports@npm:7.18.6" @@ -263,6 +347,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-module-imports@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 9ac2b0404fa38b80bdf2653fbeaf8e8a43ccb41bd505f9741d820ed95d3c4e037c62a1bcdcb6c9527d7798d2e595924c4d025daed73283badc180ada2c9c49ad + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.18.6, @babel/helper-module-transforms@npm:^7.20.11, @babel/helper-module-transforms@npm:^7.21.2, @babel/helper-module-transforms@npm:^7.21.5, @babel/helper-module-transforms@npm:^7.22.1": version: 7.22.1 resolution: "@babel/helper-module-transforms@npm:7.22.1" @@ -279,6 +372,22 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-module-transforms@npm:7.22.5" + dependencies: + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-module-imports": ^7.22.5 + "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: 8985dc0d971fd17c467e8b84fe0f50f3dd8610e33b6c86e5b3ca8e8859f9448bcc5c84e08a2a14285ef388351c0484797081c8f05a03770bf44fc27bf4900e68 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.0.0, @babel/helper-optimise-call-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-optimise-call-expression@npm:7.18.6" @@ -288,6 +397,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.18.9, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": version: 7.20.2 resolution: "@babel/helper-plugin-utils@npm:7.20.2" @@ -302,6 +420,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-plugin-utils@npm:7.22.5" + checksum: c0fc7227076b6041acd2f0e818145d2e8c41968cc52fb5ca70eed48e21b8fe6dd88a0a91cbddf4951e33647336eb5ae184747ca706817ca3bef5e9e905151ff5 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.18.9": version: 7.18.9 resolution: "@babel/helper-remap-async-to-generator@npm:7.18.9" @@ -330,6 +455,20 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-replace-supers@npm:7.22.5" + dependencies: + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: af29deff6c6dc3fa2d1a517390716aa3f4d329855e8689f1d5c3cb07c1b898e614a5e175f1826bb58e9ff1480e6552885a71a9a0ba5161787aaafa2c79b216cc + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.20.2": version: 7.20.2 resolution: "@babel/helper-simple-access@npm:7.20.2" @@ -348,6 +487,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-simple-access@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: fe9686714caf7d70aedb46c3cce090f8b915b206e09225f1e4dbc416786c2fdbbee40b38b23c268b7ccef749dd2db35f255338fb4f2444429874d900dede5ad2 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0": version: 7.20.0 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.20.0" @@ -357,6 +505,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-split-export-declaration@npm:7.18.6" @@ -366,6 +523,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-split-export-declaration@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: d10e05a02f49c1f7c578cea63d2ac55356501bbf58856d97ac9bfde4957faee21ae97c7f566aa309e38a256eef58b58e5b670a7f568b362c00e93dfffe072650 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.19.4": version: 7.19.4 resolution: "@babel/helper-string-parser@npm:7.19.4" @@ -380,6 +546,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-string-parser@npm:7.22.5" + checksum: 836851ca5ec813077bbb303acc992d75a360267aa3b5de7134d220411c852a6f17de7c0d0b8c8dcc0f567f67874c00f4528672b2a4f1bc978a3ada64c8c78467 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1": version: 7.19.1 resolution: "@babel/helper-validator-identifier@npm:7.19.1" @@ -387,6 +560,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-validator-identifier@npm:7.22.5" + checksum: 7f0f30113474a28298c12161763b49de5018732290ca4de13cdaefd4fd0d635a6fe3f6686c37a02905fb1e64f21a5ee2b55140cf7b070e729f1bd66866506aea + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.21.0": version: 7.21.0 resolution: "@babel/helper-validator-option@npm:7.21.0" @@ -394,6 +574,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-validator-option@npm:7.22.5" + checksum: bbeca8a85ee86990215c0424997438b388b8d642d69b9f86c375a174d3cdeb270efafd1ff128bc7a1d370923d13b6e45829ba8581c027620e83e3a80c5c414b3 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.18.9": version: 7.20.5 resolution: "@babel/helper-wrap-function@npm:7.20.5" @@ -428,6 +615,17 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/highlight@npm:7.22.5" + dependencies: + "@babel/helper-validator-identifier": ^7.22.5 + chalk: ^2.0.0 + js-tokens: ^4.0.0 + checksum: f61ae6de6ee0ea8d9b5bcf2a532faec5ab0a1dc0f7c640e5047fc61630a0edb88b18d8c92eb06566d30da7a27db841aca11820ecd3ebe9ce514c9350fbed39c4 + languageName: node + linkType: hard + "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.9, @babel/parser@npm:^7.22.0, @babel/parser@npm:^7.22.4": version: 7.22.4 resolution: "@babel/parser@npm:7.22.4" @@ -446,6 +644,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/parser@npm:7.22.5" + bin: + parser: ./bin/babel-parser.js + checksum: 470ebba516417ce8683b36e2eddd56dcfecb32c54b9bb507e28eb76b30d1c3e618fd0cfeee1f64d8357c2254514e1a19e32885cfb4e73149f4ae875436a6d59c + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6" @@ -802,6 +1009,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 8829d30c2617ab31393d99cec2978e41f014f4ac6f01a1cecf4c4dd8320c3ec12fdc3ce121126b2d8d32f6887e99ca1a0bad53dedb1e6ad165640b92b24980ce + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -901,6 +1119,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 8ab7718fbb026d64da93681a57797d60326097fd7cb930380c8bffd9eb101689e90142c760a14b51e8e69c88a73ba3da956cb4520a3b0c65743aee5c71ef360a + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1253,6 +1482,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.22.5" + dependencies: + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-simple-access": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 2067aca8f6454d54ffcce69b02c457cfa61428e11372f6a1d99ff4fcfbb55c396ed2ca6ca886bf06c852e38c1a205b8095921b2364fd0243f3e66bc1dda61caa + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.20.11, @babel/plugin-transform-modules-systemjs@npm:^7.22.3": version: 7.22.3 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.22.3" @@ -1607,6 +1849,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-typescript@npm:7.22.5" + dependencies: + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-typescript": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: d12f1ca1ef1f2a54432eb044d2999705d1205ebe211c2a7f05b12e8eb2d2a461fd7657b5486b2f2f1efe7c0c0dc8e80725b767073d40fe4ae059a7af057b05e4 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.18.10": version: 7.18.10 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.18.10" @@ -1894,18 +2150,18 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:7.21.5": - version: 7.21.5 - resolution: "@babel/preset-typescript@npm:7.21.5" +"@babel/preset-typescript@npm:7.22.5": + version: 7.22.5 + resolution: "@babel/preset-typescript@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-validator-option": ^7.21.0 - "@babel/plugin-syntax-jsx": ^7.21.4 - "@babel/plugin-transform-modules-commonjs": ^7.21.5 - "@babel/plugin-transform-typescript": ^7.21.3 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-validator-option": ^7.22.5 + "@babel/plugin-syntax-jsx": ^7.22.5 + "@babel/plugin-transform-modules-commonjs": ^7.22.5 + "@babel/plugin-transform-typescript": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e7b35c435139eec1d6bd9f57e8f3eb79bfc2da2c57a34ad9e9ea848ba4ecd72791cf4102df456604ab07c7f4518525b0764754b6dd5898036608b351e0792448 + checksum: 7be1670cb4404797d3a473bd72d66eb2b3e0f2f8a672a5e40bdb0812cc66085ec84bcd7b896709764cabf042fdc6b7f2d4755ac7cce10515eb596ff61dab5154 languageName: node linkType: hard @@ -1976,6 +2232,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/template@npm:7.22.5" + dependencies: + "@babel/code-frame": ^7.22.5 + "@babel/parser": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: c5746410164039aca61829cdb42e9a55410f43cace6f51ca443313f3d0bdfa9a5a330d0b0df73dc17ef885c72104234ae05efede37c1cc8a72dc9f93425977a3 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.21.4, @babel/traverse@npm:~7.21.2": version: 7.21.4 resolution: "@babel/traverse@npm:7.21.4" @@ -2012,6 +2279,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/traverse@npm:7.22.5" + dependencies: + "@babel/code-frame": ^7.22.5 + "@babel/generator": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/parser": ^7.22.5 + "@babel/types": ^7.22.5 + debug: ^4.1.0 + globals: ^11.1.0 + checksum: 560931422dc1761f2df723778dcb4e51ce0d02e560cf2caa49822921578f49189a5a7d053b78a32dca33e59be886a6b2200a6e24d4ae9b5086ca0ba803815694 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.5, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.5, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.3, @babel/types@npm:^7.22.4, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.22.4 resolution: "@babel/types@npm:7.22.4" @@ -2034,6 +2319,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/types@npm:7.22.5" + dependencies: + "@babel/helper-string-parser": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.5 + to-fast-properties: ^2.0.0 + checksum: c13a9c1dc7d2d1a241a2f8363540cb9af1d66e978e8984b400a20c4f38ba38ca29f06e26a0f2d49a70bad9e57615dac09c35accfddf1bb90d23cd3e0a0bab892 + languageName: node + linkType: hard + "@base2/pretty-print-object@npm:1.0.1": version: 1.0.1 resolution: "@base2/pretty-print-object@npm:1.0.1" @@ -18261,7 +18557,7 @@ __metadata: "@babel/plugin-transform-typescript": 7.22.3 "@babel/preset-env": 7.22.4 "@babel/preset-react": 7.22.3 - "@babel/preset-typescript": 7.21.5 + "@babel/preset-typescript": 7.22.5 "@babel/runtime": 7.22.3 "@betterer/betterer": 5.4.0 "@betterer/cli": 5.4.0 From 417f6ceeb62e81e905b05427cbbd7c369309b3e9 Mon Sep 17 00:00:00 2001 From: Andrej Ocenas Date: Fri, 9 Jun 2023 10:54:06 +0200 Subject: [PATCH 02/24] Grafana/ui: Fix margin in RadioButtonGroup option when only icon is present (#68899) --- .../src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx index 20e430a526c..2454124a82e 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx @@ -75,6 +75,7 @@ export function RadioButtonGroup({ {options.map((opt, i) => { const isItemDisabled = disabledOptions && opt.value && disabledOptions.includes(opt.value); const icon = opt.icon ? toIconName(opt.icon) : undefined; + const hasNonIconPart = Boolean(opt.imgUrl || opt.label || opt.component); return ( ({ fullWidth={fullWidth} ref={value === opt.value ? activeButtonRef : undefined} > - {icon && } + {icon && } {opt.imgUrl && {opt.label}} {opt.label} {opt.component ? : null} From 5a2e66676eb1bd284024680f6065a66b45f25c62 Mon Sep 17 00:00:00 2001 From: brendamuir <100768211+brendamuir@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:58:05 +0200 Subject: [PATCH 03/24] Docs:fixes alerting support escalations (#69770) * Docs:fixes alerting support escalations * updates recording rule text * adds link * fixes link * Update docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fixes relref * adds link to prometheus docs * fixes relref --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- ...reate-mimir-loki-managed-recording-rule.md | 28 ++++++------------- .../manage-notifications/create-silence.md | 4 +++ .../create-notification-templates.md | 8 +++++- .../http_api/alerting_provisioning.md | 4 +++ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md index 604222bf681..425e2d8d6db 100644 --- a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md +++ b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md @@ -18,6 +18,14 @@ weight: 400 You can create and manage recording rules for an external Grafana Mimir or Loki instance. Recording rules calculate frequently needed expressions or computationally expensive expressions in advance and save the result as a new set of time series. Querying this new time series is faster, especially for dashboards since they query the same expression every time the dashboards refresh. +**Note:** + +Recording rules are run as instant rules, which means that they run every 10s. To overwrite this configuration, update the min_interval in your custom configuration file. + +[min_interval]({{< relref "../../setup-grafana/configure-grafana" >}}) sets the minimum interval to enforce between rule evaluations. The default value is 10s which equals the scheduler interval. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as fewer evaluations are scheduled over time. + +This setting has precedence over each individual rule frequency. If a rule frequency is lower than this value, then this value is enforced. + ## Before you begin - Verify that you have write permission to the Prometheus or Loki data source. Otherwise, you will not be able to create or update Grafana Mimir managed alerting rules. @@ -44,25 +52,7 @@ To create a Grafana Mimir or Loki managed recording rule 1. In Step 2, select **Mimir or Loki recording rule** option. - Select your Loki or Prometheus data source. - Enter a PromQL or LogQL query. -1. In Step 3, add the namespace and the group. - - From the **Namespace** dropdown, 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** dropdown, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. -1. In Step 4, add the 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 recording rule or **Save and exit** to save the recording rule and go back to the Alerting page. - - - -1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. -1. Click **Alert rules**. -1. Click **+ Create alert rule**. -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** dropdown, select **Mimir / Loki managed alert**. - - From the **Select data source** dropdown, select an external Prometheus, an external Loki, or a Grafana Cloud data source. - - 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 3, add evaluation behavior. +1. In Step 3, add alert evaluation behavior. - Enter a valid **For** duration. The expression has to be true for this long for the alert to be fired. 1. In Step 4, add additional metadata associated with the rule. - From the **Namespace** dropdown, 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" >}}). diff --git a/docs/sources/alerting/manage-notifications/create-silence.md b/docs/sources/alerting/manage-notifications/create-silence.md index 8553a96dbd7..e2550436fc3 100644 --- a/docs/sources/alerting/manage-notifications/create-silence.md +++ b/docs/sources/alerting/manage-notifications/create-silence.md @@ -61,3 +61,7 @@ To remove a silence, complete the following steps. 1. Select the silence you want to end, then click **Unsilence**. > **Note:** You cannot remove a silence manually. Silences that have ended are retained and listed for five days. + +## Useful links + +[Aggregation operators](/docs/prometheus/latest/querying/operators/#aggregation-operators) diff --git a/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md b/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md index 525206b5643..138e782c253 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md @@ -179,7 +179,13 @@ Template the title of a Slack message to contain the number of firing and resolv ## Template the content of a Slack message -Template the content of a Slack message to contain a description of all firing and resolved alerts, including their labels, annotations, Silence URL and Dashboard URL: +Template the content of a Slack message to contain a description of all firing and resolved alerts, including their labels, annotations, Silence URL and Dashboard URL. + +**Note:** + +This template is for Grafana-managed alerts only. +To use the template for Grafana Mimir/Loki-managed alerts, delete the references to DashboardURL and SilenceURL. +For more information, see the [Prometheus documentation on notifications](https://prometheus.io/docs/alerting/latest/notifications/). ``` 1 firing alert(s): diff --git a/docs/sources/developers/http_api/alerting_provisioning.md b/docs/sources/developers/http_api/alerting_provisioning.md index 6eb756452dc..491757a567b 100644 --- a/docs/sources/developers/http_api/alerting_provisioning.md +++ b/docs/sources/developers/http_api/alerting_provisioning.md @@ -52,6 +52,10 @@ title: 'Alerting Provisioning HTTP API ' ### Contact points +**Note:** + +Contact point provisioning is for Grafana-managed alerts only. + | Method | URI | Name | Summary | | ------ | ----------------------------------------- | --------------------------------------------------------- | --------------------------------- | | DELETE | /api/v1/provisioning/contact-points/{UID} | [route delete contactpoints](#route-delete-contactpoints) | Delete a contact point. | From 1696bc201eeac25f28184bfa47bb0960c1c90b73 Mon Sep 17 00:00:00 2001 From: Domas Date: Fri, 9 Jun 2023 12:17:05 +0300 Subject: [PATCH 04/24] Tempo/ServiceGraph: Specify explicit field types (#69759) Assign field types to service graph fields --- .../datasource/tempo/graphTransform.test.ts | 35 ++++++++++++++++++- .../datasource/tempo/graphTransform.ts | 24 ++++++++----- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/public/app/plugins/datasource/tempo/graphTransform.test.ts b/public/app/plugins/datasource/tempo/graphTransform.test.ts index c5e8f9f049b..a81f776de51 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.test.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.test.ts @@ -1,4 +1,4 @@ -import { DataFrameView, dateTime, createDataFrame } from '@grafana/data'; +import { DataFrameView, dateTime, createDataFrame, FieldType } from '@grafana/data'; import { createGraphFrames, mapPromMetricsToServiceMap } from './graphTransform'; import { bigResponse } from './testResponse'; @@ -59,6 +59,26 @@ describe('createGraphFrames', () => { }); }); +it('assigns correct field type even if values are numbers', async () => { + const range = { + from: dateTime('2000-01-01T00:00:00'), + to: dateTime('2000-01-01T00:01:00'), + }; + const { nodes } = mapPromMetricsToServiceMap([{ data: [serverIsANumber, serverIsANumber] }], { + ...range, + raw: range, + }); + + expect(nodes.fields).toMatchObject([ + { name: 'id', values: ['0', '1'], type: FieldType.string }, + { name: 'title', values: ['0', '1'], type: FieldType.string }, + { name: 'mainstat', values: [NaN, NaN], type: FieldType.number }, + { name: 'secondarystat', values: [10, 20], type: FieldType.number }, + { name: 'arc__success', values: [1, 1], type: FieldType.number }, + { name: 'arc__failed', values: [0, 0], type: FieldType.number }, + ]); +}); + describe('mapPromMetricsToServiceMap', () => { it('transforms prom metrics to service graph', async () => { const range = { @@ -191,3 +211,16 @@ const invalidFailedPromMetric = createDataFrame({ { name: 'Value #traces_service_graph_request_failed_total', values: [20, 40] }, ], }); + +const serverIsANumber = createDataFrame({ + refId: 'traces_service_graph_request_total', + fields: [ + { name: 'Time', values: [1628169788000, 1628169788000] }, + { name: 'client', values: ['0', '1'] }, + { name: 'instance', values: ['127.0.0.1:12345', '127.0.0.1:12345'] }, + { name: 'job', values: ['local_scrape', 'local_scrape'] }, + { name: 'server', values: ['0', '1'] }, + { name: 'tempo_config', values: ['default', 'default'] }, + { name: 'Value #traces_service_graph_request_total', values: [10, 20] }, + ], +}); diff --git a/public/app/plugins/datasource/tempo/graphTransform.ts b/public/app/plugins/datasource/tempo/graphTransform.ts index 292d059876f..eb36c6f8737 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.ts @@ -7,6 +7,7 @@ import { MutableDataFrame, NodeGraphDataFrameFieldNames as Fields, TimeRange, + FieldType, } from '@grafana/data'; import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../core/utils/tracing'; @@ -188,28 +189,35 @@ function createServiceMapDataFrames() { } const nodes = createDF('Nodes', [ - { name: Fields.id }, - { name: Fields.title, config: { displayName: 'Service name' } }, - { name: Fields.mainStat, config: { unit: 'ms/r', displayName: 'Average response time' } }, + { name: Fields.id, type: FieldType.string }, + { name: Fields.title, type: FieldType.string, config: { displayName: 'Service name' } }, + { name: Fields.mainStat, type: FieldType.number, config: { unit: 'ms/r', displayName: 'Average response time' } }, { name: Fields.secondaryStat, + type: FieldType.number, config: { unit: 'r/sec', displayName: 'Requests per second' }, }, { name: Fields.arc + 'success', + type: FieldType.number, config: { displayName: 'Success', color: { fixedColor: 'green', mode: FieldColorModeId.Fixed } }, }, { name: Fields.arc + 'failed', + type: FieldType.number, config: { displayName: 'Failed', color: { fixedColor: 'red', mode: FieldColorModeId.Fixed } }, }, ]); const edges = createDF('Edges', [ - { name: Fields.id }, - { name: Fields.source }, - { name: Fields.target }, - { name: Fields.mainStat, config: { unit: 'ms/r', displayName: 'Average response time' } }, - { name: Fields.secondaryStat, config: { unit: 'r/sec', displayName: 'Requests per second' } }, + { name: Fields.id, type: FieldType.string }, + { name: Fields.source, type: FieldType.string }, + { name: Fields.target, type: FieldType.string }, + { name: Fields.mainStat, type: FieldType.number, config: { unit: 'ms/r', displayName: 'Average response time' } }, + { + name: Fields.secondaryStat, + type: FieldType.number, + config: { unit: 'r/sec', displayName: 'Requests per second' }, + }, ]); return [nodes, edges]; From 3dc8255639c8afe80ec1c1597b2d48293724ee9b Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:54:51 +0100 Subject: [PATCH 05/24] Changelog: Updated changelog for 10.0.0-preview (#69837) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changelog: Updated changelog for 10.0.0-preview * prettier --------- Co-authored-by: Torkel Ödegaard --- CHANGELOG.md | 63 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 379d4f1e7cd..c475d65bdce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ ### Features and enhancements +- **Alerting:** Migrate unknown NoData\Error settings to the default. [#69010](https://github.com/grafana/grafana/issues/69010), [@grafanabot](https://github.com/grafanabot) +- **Drawer:** Position under nav & minor redesign . [#68396](https://github.com/grafana/grafana/issues/68396), [@grafanabot](https://github.com/grafanabot) +- **Navigation:** Add keyboard shortcut to navigate directly to Dashboards. [#68374](https://github.com/grafana/grafana/issues/68374), [@grafanabot](https://github.com/grafanabot) +- **Explore:** Promote exploreMixedDatasource to Stable & enable by default. [#68353](https://github.com/grafana/grafana/issues/68353), [@Elfo404](https://github.com/Elfo404) +- **Tempo:** Escape regex-sensitive characters in span name before building promql query. [#68313](https://github.com/grafana/grafana/issues/68313), [@grafanabot](https://github.com/grafanabot) +- **Drawer:** Introduce a size property that set's width percentage and minWidth . [#68128](https://github.com/grafana/grafana/issues/68128), [@grafanabot](https://github.com/grafanabot) +- **AngularDeprecation:** Show warnings in panel edit for angular panels. [#68083](https://github.com/grafana/grafana/issues/68083), [@grafanabot](https://github.com/grafanabot) +- **Dashboard:** Change add panel button to fill to remove outline border. [#68017](https://github.com/grafana/grafana/issues/68017), [@grafanabot](https://github.com/grafanabot) - **Query History:** Remove migration. [#67470](https://github.com/grafana/grafana/issues/67470), [@Elfo404](https://github.com/Elfo404) - **Alerting:** Implement template testing endpoint. [#67450](https://github.com/grafana/grafana/issues/67450), [@JacobsonMT](https://github.com/JacobsonMT) - **Trace View:** Export trace button . [#67368](https://github.com/grafana/grafana/issues/67368), [@adrapereira](https://github.com/adrapereira) @@ -100,6 +108,37 @@ ### Bug fixes +- **ResourcePicker:** Fix missing border bug on cancel button. [#69113](https://github.com/grafana/grafana/issues/69113), [@nmarrs](https://github.com/nmarrs) +- **TimeSeries:** Fix centeredZero y axis ranging when all values are 0. [#69112](https://github.com/grafana/grafana/issues/69112), [@grafanabot](https://github.com/grafanabot) +- **StatusHistory:** Fix rendering of value-mapped null. [#69108](https://github.com/grafana/grafana/issues/69108), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Fix provenance guard checks for Alertmanager configuration to not cause panic when compared nested objects. [#69094](https://github.com/grafana/grafana/issues/69094), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Add support for Alert State History Loki primary. [#69077](https://github.com/grafana/grafana/issues/69077), [@grafanabot](https://github.com/grafanabot) +- **Dashboards:** Fix undefined aria labels in Annotation Checkboxes for Programmatic Access. [#68873](https://github.com/grafana/grafana/issues/68873), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Fix stale query preview error. [#68836](https://github.com/grafana/grafana/issues/68836), [@grafanabot](https://github.com/grafanabot) +- **AnonymousAuth:** Fix concurrent read-write crash. [#68803](https://github.com/grafana/grafana/issues/68803), [@grafanabot](https://github.com/grafanabot) +- **AzureMonitor:** Ensure legacy properties containing template variables are correctly migrated. [#68792](https://github.com/grafana/grafana/issues/68792), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Add additional contact points for external AM. [#68778](https://github.com/grafana/grafana/issues/68778), [@grafanabot](https://github.com/grafanabot) +- **RBAC:** Remove legacy AC editor and admin role on new dashboard route. [#68777](https://github.com/grafana/grafana/issues/68777), [@grafanabot](https://github.com/grafanabot) +- **Azure Monitor:** Fix bug with top value so more than 10 resources can be shown . [#68725](https://github.com/grafana/grafana/issues/68725), [@grafanabot](https://github.com/grafanabot) +- **NodeGraph:** Fix overlaps preventing opening an edge context menu when nodes were too close. [#68628](https://github.com/grafana/grafana/issues/68628), [@grafanabot](https://github.com/grafanabot) +- **Plugins:** Correct the usage of mutex for gRPC plugin implementation. [#68609](https://github.com/grafana/grafana/issues/68609), [@grafanabot](https://github.com/grafanabot) +- **Azure Monitor:** Fix bug that did not show alert rule preview. [#68581](https://github.com/grafana/grafana/issues/68581), [@grafanabot](https://github.com/grafanabot) +- **FlameGraph:** Fix table sort being reset when search changes. [#68454](https://github.com/grafana/grafana/issues/68454), [@grafanabot](https://github.com/grafanabot) +- **Command Palette:** Prevent stale search results from overwriting newer results. [#68392](https://github.com/grafana/grafana/issues/68392), [@grafanabot](https://github.com/grafanabot) +- **Search:** Fix Search returning results out of order. [#68387](https://github.com/grafana/grafana/issues/68387), [@joshhunt](https://github.com/joshhunt) +- **Explore:** Remove data source onboarding page. [#68381](https://github.com/grafana/grafana/issues/68381), [@grafanabot](https://github.com/grafanabot) +- **Flamegraph:** Fix tooltip positioning. [#68312](https://github.com/grafana/grafana/issues/68312), [@grafanabot](https://github.com/grafanabot) +- **Pyroscope:** Add authentication when calling backendType resource API. [#68311](https://github.com/grafana/grafana/issues/68311), [@grafanabot](https://github.com/grafanabot) +- **Histogram:** Respect min/max panel settings for x-axis. [#68245](https://github.com/grafana/grafana/issues/68245), [@grafanabot](https://github.com/grafanabot) +- **QueryRow:** Make toggle actions screen-readers accessible. [#68210](https://github.com/grafana/grafana/issues/68210), [@grafanabot](https://github.com/grafanabot) +- **Heatmap:** Fix color rendering for value ranges < 1. [#68164](https://github.com/grafana/grafana/issues/68164), [@grafanabot](https://github.com/grafanabot) +- **Heatmap:** Handle unsorted timestamps in calculate mode. [#68151](https://github.com/grafana/grafana/issues/68151), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Fixes Alert list panel "ungrouped" regression. [#68090](https://github.com/grafana/grafana/issues/68090), [@grafanabot](https://github.com/grafanabot) +- **Alerting:** Show export button for org admins. [#67995](https://github.com/grafana/grafana/issues/67995), [@grafanabot](https://github.com/grafanabot) +- **Navigation:** Fix 'Page not found' when sending or going back from 'Invitate user' page. [#67972](https://github.com/grafana/grafana/issues/67972), [@grafanabot](https://github.com/grafanabot) +- **InspectDrawer:** Fixes issue with double scrollbars. [#67888](https://github.com/grafana/grafana/issues/67888), [@grafanabot](https://github.com/grafanabot) +- **Connections:** Show core datasource plugins as well. [#67886](https://github.com/grafana/grafana/issues/67886), [@grafanabot](https://github.com/grafanabot) +- **Gauge:** Set min and max for percent unit. [#67719](https://github.com/grafana/grafana/issues/67719), [@grafanabot](https://github.com/grafanabot) - **TimeSeries:** Fix leading null-fill for missing intervals. [#67570](https://github.com/grafana/grafana/issues/67570), [@leeoniya](https://github.com/leeoniya) - **Pyroscope:** Fix autodetection in case of using Phlare backend. [#67536](https://github.com/grafana/grafana/issues/67536), [@aocenas](https://github.com/aocenas) - **Dashboard:** Revert fixed header shown on mobile devices in the new panel header. [#67510](https://github.com/grafana/grafana/issues/67510), [@axelavargas](https://github.com/axelavargas) @@ -181,13 +220,15 @@ The deprecated `plugin:test` and `plugin:dev` commands in the Grafana Toolkit ha The type signature of the `testDatasource()` method on the `DataSourceWithBackend` class [has changed](https://github.com/grafana/grafana/pull/67014/files/a5608dc4f27ab4459e725b22ff60b8fc05390c08#diff-c58fc1a09e9b9b17e5f45efbfb646273e69145f7687facb134440da4edafc745R263), the returned Promise is now typed stricter, which is probably going to cause type-errors while building plugins against the latest Grafana versions. -````typescript +```typescript // Before abstract testDatasource(): Promise; // After abstract testDatasource(): Promise; -``` Issue [#67014](https://github.com/grafana/grafana/issues/67014) +``` + +Issue [#67014](https://github.com/grafana/grafana/issues/67014) Grafana requires an Elasticsearch version of 7.16 or newer. If you use an older Elasticsearch version, you will get warnings in the query editor and on the datasource configuration page. Issue [#66928](https://github.com/grafana/grafana/issues/66928) @@ -200,19 +241,19 @@ We've removed some now unused properties from the `NavModel` interface. Issue [# We removed previously deprecated components from `@grafana/data` : `getLogLevel`, `getLogLevelFromKey`, `addLogLevelToSeries`, `LogsParser`, `LogsParsers`, `calculateFieldStats`, `calculateLogsLabelStats`, `calculateStats`, `getParser`, `sortInAscendingOrder`, `sortInDescendingOrder`, `sortLogsResult`, `sortLogRows`, `checkLogsError`, `escapeUnescapedString`. Issue [#66271](https://github.com/grafana/grafana/issues/66271) We removed previously deprecated components from `@grafana/ui` : `LogLabels`, `LogMessageAnsi`, `LogRows`, `getLogRowStyles`. - Issue [#66268](https://github.com/grafana/grafana/issues/66268) +Issue [#66268](https://github.com/grafana/grafana/issues/66268) -We removed previously deprecated `DataSourceWithLogsVolumeSupport` that was replaced with `DataSourceWithSupplementaryQueriesSupport`. Both APIs are for internal use only. Issue [#66266](https://github.com/grafana/grafana/issues/66266) +We removed previously deprecated `DataSourceWithLogsVolumeSupport` that was replaced with `DataSourceWithSupplementaryQueriesSupport`. Both APIs are for internal use only. Issue [#66266](https://github.com/grafana/grafana/issues/66266) -Additional functions (map/filter/forEach/iterator) have been added to the root Vector interface. Any code using vectors will continue to work unchanged, but in the rare case that you have implemented Vector directly, it be missing these functions. The easiest fix is to extend [FunctionalVector](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/vector/FunctionalVector.ts). +Additional functions (map/filter/forEach/iterator) have been added to the root Vector interface. Any code using vectors will continue to work unchanged, but in the rare case that you have implemented Vector directly, it be missing these functions. The easiest fix is to extend [FunctionalVector](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/vector/FunctionalVector.ts). The `ArrayVector` class now extends the native JavaScript `Array` and gains all of its prototype/instance methods as a result. Issue [#66187](https://github.com/grafana/grafana/issues/66187) We've removed the ability for functions to be passed as children to the `Dropdown` component. Previously, this was used to access the `isOpen` state of the dropdown. This can be now be achieved with the `onVisibleChange` prop. Before: -```` +``` return ( {(isOpen) => @@ -220,12 +261,11 @@ return ( } ); - ``` After: -``` +```` const [isOpen, setIsOpen] = useState(false); ... @@ -235,8 +275,7 @@ return ( ); - -````Issue [#65467](https://github.com/grafana/grafana/issues/65467) +``` Issue [#65467](https://github.com/grafana/grafana/issues/65467) (relevant for plugin developers) The deprecated internal `dashboardId` is now removed from the request context. For usage tracking use the `dashboardUid` @@ -3317,8 +3356,8 @@ The change in behavior is that negative-valued series are now stacked downwards The meaning of the default data source has now changed from being a persisted property in a panel. Before when you selected the default data source for a panel and later changed the default data source to another data source it would change all panels who were configured to use the default data source. From now on the default data source is just the default for new panels and changing the default will not impact any currently saved dashboards. Issue [#45132](https://github.com/grafana/grafana/issues/45132) -The Tooltip component provided by `@grafana/ui` is no longer automatically interactive (that is you can hover onto it and click a link or select text). It will from now on by default close automatically when you mouse out from the trigger element. To make tooltips behave like before set the new `interactive` property to true. - Issue [#45053](https://github.com/grafana/grafana/issues/45053) +The Tooltip component provided by `@grafana/ui` is no longer automatically interactive (that is you can hover onto it and click a link or select text). It will from now on by default close automatically when you mouse out from the trigger element. To make tooltips behave like before set the new `interactive` property to true. +Issue [#45053](https://github.com/grafana/grafana/issues/45053) ### Deprecations From 9f18e0ccf3531af837e10581d38fc5ea711af362 Mon Sep 17 00:00:00 2001 From: Will Browne Date: Fri, 9 Jun 2023 12:08:26 +0200 Subject: [PATCH 06/24] Plugins: Re-use plugin registry mocks from fakes package (#69840) re-use mocks from fakes package --- pkg/plugins/manager/process/process_test.go | 63 ++++------- pkg/plugins/manager/store/store_test.go | 111 ++++++++------------ 2 files changed, 62 insertions(+), 112 deletions(-) diff --git a/pkg/plugins/manager/process/process_test.go b/pkg/plugins/manager/process/process_test.go index 275b743bd0c..1a1d6849a86 100644 --- a/pkg/plugins/manager/process/process_test.go +++ b/pkg/plugins/manager/process/process_test.go @@ -10,11 +10,12 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/plugins/log" + "github.com/grafana/grafana/pkg/plugins/manager/fakes" ) func TestProcessManager_Start(t *testing.T) { t.Run("Plugin not found in registry", func(t *testing.T) { - m := NewManager(newFakePluginRegistry(map[string]*plugins.Plugin{})) + m := NewManager(fakes.NewFakePluginRegistry()) err := m.Start(context.Background(), "non-existing-datasource") require.ErrorIs(t, err, backendplugin.ErrPluginNotRegistered) }) @@ -63,9 +64,11 @@ func TestProcessManager_Start(t *testing.T) { plugin.SignatureError = tc.signatureError }) - m := NewManager(newFakePluginRegistry(map[string]*plugins.Plugin{ - p.ID: p, - })) + m := NewManager(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p.ID: p, + }}, + ) err := m.Start(context.Background(), p.ID) require.NoError(t, err) @@ -83,7 +86,7 @@ func TestProcessManager_Start(t *testing.T) { func TestProcessManager_Stop(t *testing.T) { t.Run("Plugin not found in registry", func(t *testing.T) { - m := NewManager(newFakePluginRegistry(map[string]*plugins.Plugin{})) + m := NewManager(fakes.NewFakePluginRegistry()) err := m.Stop(context.Background(), "non-existing-datasource") require.ErrorIs(t, err, backendplugin.ErrPluginNotRegistered) }) @@ -97,9 +100,11 @@ func TestProcessManager_Stop(t *testing.T) { plugin.Backend = true }) - m := NewManager(newFakePluginRegistry(map[string]*plugins.Plugin{ - pluginID: p, - })) + m := NewManager(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + pluginID: p, + }}, + ) err := m.Stop(context.Background(), pluginID) require.NoError(t, err) @@ -116,9 +121,11 @@ func TestProcessManager_ManagedBackendPluginLifecycle(t *testing.T) { plugin.Backend = true }) - m := NewManager(newFakePluginRegistry(map[string]*plugins.Plugin{ - p.ID: p, - })) + m := NewManager(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p.ID: p, + }}, + ) err := m.Start(context.Background(), p.ID) require.NoError(t, err) @@ -162,40 +169,6 @@ func TestProcessManager_ManagedBackendPluginLifecycle(t *testing.T) { }) } -type fakePluginRegistry struct { - store map[string]*plugins.Plugin -} - -func newFakePluginRegistry(m map[string]*plugins.Plugin) *fakePluginRegistry { - return &fakePluginRegistry{ - store: m, - } -} - -func (f *fakePluginRegistry) Plugin(_ context.Context, id string) (*plugins.Plugin, bool) { - p, exists := f.store[id] - return p, exists -} - -func (f *fakePluginRegistry) Plugins(_ context.Context) []*plugins.Plugin { - var res []*plugins.Plugin - - for _, p := range f.store { - res = append(res, p) - } - return res -} - -func (f *fakePluginRegistry) Add(_ context.Context, p *plugins.Plugin) error { - f.store[p.ID] = p - return nil -} - -func (f *fakePluginRegistry) Remove(_ context.Context, id string) error { - delete(f.store, id) - return nil -} - type fakeBackendPlugin struct { managed bool diff --git a/pkg/plugins/manager/store/store_test.go b/pkg/plugins/manager/store/store_test.go index 6ff8bea4eaa..8772ca9824f 100644 --- a/pkg/plugins/manager/store/store_test.go +++ b/pkg/plugins/manager/store/store_test.go @@ -54,10 +54,12 @@ func TestStore_Plugin(t *testing.T) { p1.RegisterClient(&DecommissionedPlugin{}) p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel"}} - ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ - p1.ID: p1, - p2.ID: p2, - })) + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p1.ID: p1, + p2.ID: p2, + }, + }) p, exists := ps.Plugin(context.Background(), p1.ID) require.False(t, exists) @@ -78,13 +80,15 @@ func TestStore_Plugins(t *testing.T) { p5 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "e-test-panel", Type: plugins.TypePanel}} p5.RegisterClient(&DecommissionedPlugin{}) - ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ - p1.ID: p1, - p2.ID: p2, - p3.ID: p3, - p4.ID: p4, - p5.ID: p5, - })) + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p1.ID: p1, + p2.ID: p2, + p3.ID: p3, + p4.ID: p4, + p5.ID: p5, + }, + }) pss := ps.Plugins(context.Background()) require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO(), p2.ToDTO(), p3.ToDTO(), p4.ToDTO()}) @@ -113,14 +117,16 @@ func TestStore_Routes(t *testing.T) { p6 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "f-test-app", Type: plugins.TypeApp}} p6.RegisterClient(&DecommissionedPlugin{}) - ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ - p1.ID: p1, - p2.ID: p2, - p3.ID: p3, - p4.ID: p4, - p5.ID: p5, - p6.ID: p6, - })) + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p1.ID: p1, + p2.ID: p2, + p3.ID: p3, + p4.ID: p4, + p5.ID: p5, + p6.ID: p6, + }, + }) sr := func(p *plugins.Plugin) *plugins.StaticRoute { return &plugins.StaticRoute{PluginID: p.ID, Directory: p.FS.Base()} @@ -137,11 +143,13 @@ func TestStore_Renderer(t *testing.T) { p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel", Type: plugins.TypePanel}} p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-app", Type: plugins.TypeApp}} - ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ - p1.ID: p1, - p2.ID: p2, - p3.ID: p3, - })) + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p1.ID: p1, + p2.ID: p2, + p3.ID: p3, + }, + }) r := ps.Renderer(context.Background()) require.Equal(t, p1, r) @@ -155,12 +163,14 @@ func TestStore_SecretsManager(t *testing.T) { p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-secrets", Type: plugins.TypeSecretsManager}} p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-datasource", Type: plugins.TypeDataSource}} - ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ - p1.ID: p1, - p2.ID: p2, - p3.ID: p3, - p4.ID: p4, - })) + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ + p1.ID: p1, + p2.ID: p2, + p3.ID: p3, + p4.ID: p4, + }, + }) r := ps.SecretsManager(context.Background()) require.Equal(t, p3, r) @@ -173,12 +183,12 @@ func TestStore_availablePlugins(t *testing.T) { p1.RegisterClient(&DecommissionedPlugin{}) p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-app"}} - ps := New( - newFakePluginRegistry(map[string]*plugins.Plugin{ + ps := New(&fakes.FakePluginRegistry{ + Store: map[string]*plugins.Plugin{ p1.ID: p1, p2.ID: p2, - }), - ) + }, + }) aps := ps.availablePlugins(context.Background()) require.Len(t, aps, 1) @@ -197,36 +207,3 @@ func (p *DecommissionedPlugin) Decommission() error { func (p *DecommissionedPlugin) IsDecommissioned() bool { return true } - -type fakePluginRegistry struct { - store map[string]*plugins.Plugin -} - -func newFakePluginRegistry(m map[string]*plugins.Plugin) *fakePluginRegistry { - return &fakePluginRegistry{ - store: m, - } -} - -func (f *fakePluginRegistry) Plugin(_ context.Context, id string) (*plugins.Plugin, bool) { - p, exists := f.store[id] - return p, exists -} - -func (f *fakePluginRegistry) Plugins(_ context.Context) []*plugins.Plugin { - var res []*plugins.Plugin - for _, p := range f.store { - res = append(res, p) - } - return res -} - -func (f *fakePluginRegistry) Add(_ context.Context, p *plugins.Plugin) error { - f.store[p.ID] = p - return nil -} - -func (f *fakePluginRegistry) Remove(_ context.Context, id string) error { - delete(f.store, id) - return nil -} From 3341229bc24e0aba2b6263ba6c66f45c0448db5d Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Fri, 9 Jun 2023 13:57:46 +0300 Subject: [PATCH 07/24] Chore: InfluxDB - Reformatting and restructuring (#69669) * Reformatting and restructuring * Update unit test * Export as function --- .betterer.results | 3 -- .../query/influxql/InfluxCheatSheet.tsx | 4 +- .../editor/query/influxql/InfluxStartPage.tsx | 12 ++--- .../query/influxql/code/RawInfluxQLEditor.tsx | 2 +- .../hooks/useRetentionPolicies.test.ts | 44 +++++++++++++++++ .../influxql/hooks/useRetentionPolicies.ts | 15 ++++++ .../hooks/useShadowedState.test.ts | 0 .../{ => influxql}/hooks/useShadowedState.ts | 0 .../editor/query/influxql/utils/filterTags.ts | 7 +++ .../utils/getTemplateVariableOptions.ts | 12 +++++ .../utils/withTemplateVariableOptions.ts | 16 ++++++ .../editor/query/influxql/utils/wrapper.ts | 9 ++++ .../query/influxql/visual/InputSection.tsx | 2 +- .../editor/query/influxql/visual/Seg.tsx | 2 +- .../influxql/visual/VisualInfluxQLEditor.tsx | 49 +++---------------- .../app/plugins/datasource/influxdb/module.ts | 2 +- .../datasource/influxdb/specs/mocks.ts | 2 +- 17 files changed, 119 insertions(+), 62 deletions(-) create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.test.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.ts rename public/app/plugins/datasource/influxdb/components/editor/query/{ => influxql}/hooks/useShadowedState.test.ts (100%) rename public/app/plugins/datasource/influxdb/components/editor/query/{ => influxql}/hooks/useShadowedState.ts (100%) create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/filterTags.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/getTemplateVariableOptions.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/withTemplateVariableOptions.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/wrapper.ts diff --git a/.betterer.results b/.betterer.results index a5ae922b47a..46ecf2ed512 100644 --- a/.betterer.results +++ b/.betterer.results @@ -4144,9 +4144,6 @@ 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/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/datasource/influxdb/datasource.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx index 7bf562c2cff..04b573159c6 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxCheatSheet.tsx @@ -8,7 +8,7 @@ const CHEAT_SHEET_ITEMS = [ }, ]; -const InfluxCheatSheet = (props: any) => ( +export const InfluxCheatSheet = () => (

InfluxDB Cheat Sheet

{CHEAT_SHEET_ITEMS.map((item) => ( @@ -19,5 +19,3 @@ const InfluxCheatSheet = (props: any) => ( ))}
); - -export default InfluxCheatSheet; diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxStartPage.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxStartPage.tsx index f5ac86a24d2..10f35190d08 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxStartPage.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/InfluxStartPage.tsx @@ -1,11 +1,7 @@ -import React, { PureComponent } from 'react'; +import React from 'react'; -import { QueryEditorHelpProps } from '@grafana/data'; +import { InfluxCheatSheet } from './InfluxCheatSheet'; -import InfluxCheatSheet from './InfluxCheatSheet'; - -export default class InfluxStartPage extends PureComponent { - render() { - return ; - } +export function InfluxStartPage() { + return ; } diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/code/RawInfluxQLEditor.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/code/RawInfluxQLEditor.tsx index 887bec9ee93..0df57b7b26d 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/code/RawInfluxQLEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/code/RawInfluxQLEditor.tsx @@ -4,7 +4,7 @@ import { HorizontalGroup, InlineFormLabel, Input, Select, TextArea } from '@graf import { InfluxQuery } from '../../../../../types'; import { DEFAULT_RESULT_FORMAT, RESULT_FORMATS } from '../../../constants'; -import { useShadowedState } from '../../hooks/useShadowedState'; +import { useShadowedState } from '../hooks/useShadowedState'; type Props = { query: InfluxQuery; diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.test.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.test.ts new file mode 100644 index 00000000000..e4648e2f1e7 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.test.ts @@ -0,0 +1,44 @@ +import { renderHook } from '@testing-library/react-hooks'; + +import config from 'app/core/config'; + +import { getMockDS, getMockDSInstanceSettings, mockBackendService } from '../../../../../specs/mocks'; + +import { useRetentionPolicies } from './useRetentionPolicies'; + +jest.mock('@grafana/runtime', () => ({ + ...jest.requireActual('@grafana/runtime'), +})); + +describe('useRetentionPolicies', () => { + it('should return all policies when influxdbBackendMigration feature toggle enabled', async () => { + const instanceSettings = getMockDSInstanceSettings(); + const datasource = getMockDS(instanceSettings); + mockBackendService(response); + + config.featureToggles.influxdbBackendMigration = true; + const { result, waitForNextUpdate } = renderHook(() => useRetentionPolicies(datasource)); + await waitForNextUpdate(); + expect(result.current.retentionPolicies.length).toEqual(4); + expect(result.current.retentionPolicies[0]).toEqual('autogen'); + }); +}); + +const response = { + data: { + results: { + metadataQuery: { + status: 200, + frames: [ + { + schema: { + refId: 'metadataQuery', + fields: [{ name: 'value', type: 'string', typeInfo: { frame: 'string' } }], + }, + data: { values: [['autogen', 'bar', '5m_avg', '1m_avg']] }, + }, + ], + }, + }, + }, +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.ts new file mode 100644 index 00000000000..c25b795294c --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useRetentionPolicies.ts @@ -0,0 +1,15 @@ +import { useEffect, useState } from 'react'; + +import InfluxDatasource from '../../../../../datasource'; +import { getAllPolicies } from '../../../../../influxql_metadata_query'; + +export const useRetentionPolicies = (datasource: InfluxDatasource) => { + const [retentionPolicies, setRetentionPolicies] = useState([]); + useEffect(() => { + getAllPolicies(datasource).then((data) => { + setRetentionPolicies(data); + }); + }, [datasource]); + + return { retentionPolicies }; +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/hooks/useShadowedState.test.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useShadowedState.test.ts similarity index 100% rename from public/app/plugins/datasource/influxdb/components/editor/query/hooks/useShadowedState.test.ts rename to public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useShadowedState.test.ts diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/hooks/useShadowedState.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useShadowedState.ts similarity index 100% rename from public/app/plugins/datasource/influxdb/components/editor/query/hooks/useShadowedState.ts rename to public/app/plugins/datasource/influxdb/components/editor/query/influxql/hooks/useShadowedState.ts diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/filterTags.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/filterTags.ts new file mode 100644 index 00000000000..904de835063 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/filterTags.ts @@ -0,0 +1,7 @@ +// it is possible to add fields into the `InfluxQueryTag` structures, and they do work, +// but in some cases, when we do metadata queries, we have to remove them from the queries. +import { InfluxQueryTag } from '../../../../../types'; + +export function filterTags(parts: InfluxQueryTag[], allTagKeys: Set): InfluxQueryTag[] { + return parts.filter((t) => t.key.endsWith('::tag') || allTagKeys.has(t.key + '::tag')); +} diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/getTemplateVariableOptions.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/getTemplateVariableOptions.ts new file mode 100644 index 00000000000..51db862e4d9 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/getTemplateVariableOptions.ts @@ -0,0 +1,12 @@ +import { TypedVariableModel } from '@grafana/data/src'; +import { getTemplateSrv } from '@grafana/runtime/src'; + +export function getTemplateVariableOptions(wrapper: (v: TypedVariableModel) => string) { + return ( + getTemplateSrv() + .getVariables() + // we make them regex-params, i'm not 100% sure why. + // probably because this way multi-value variables work ok too. + .map(wrapper) + ); +} diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/withTemplateVariableOptions.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/withTemplateVariableOptions.ts new file mode 100644 index 00000000000..89bd1372bcd --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/withTemplateVariableOptions.ts @@ -0,0 +1,16 @@ +// helper function to make it easy to call this from the widget-render-code +import { TypedVariableModel } from '@grafana/data/src'; + +import { getTemplateVariableOptions } from './getTemplateVariableOptions'; + +export function withTemplateVariableOptions( + optionsPromise: Promise, + wrapper: (v: TypedVariableModel) => string, + filter?: string +): Promise { + let templateVariableOptions = getTemplateVariableOptions(wrapper); + if (filter) { + templateVariableOptions = templateVariableOptions.filter((tvo) => tvo.indexOf(filter) > -1); + } + return optionsPromise.then((options) => [...templateVariableOptions, ...options]); +} diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/wrapper.ts b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/wrapper.ts new file mode 100644 index 00000000000..769a9a435a4 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/utils/wrapper.ts @@ -0,0 +1,9 @@ +import { TypedVariableModel } from '@grafana/data/src'; + +export function wrapRegex(v: TypedVariableModel): string { + return `/^$${v.name}$/`; +} + +export function wrapPure(v: TypedVariableModel): string { + return `$${v.name}`; +} diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/InputSection.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/InputSection.tsx index 6bf9e24e9b5..71b9fad90d3 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/InputSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/InputSection.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { Input } from '@grafana/ui'; -import { useShadowedState } from '../../hooks/useShadowedState'; +import { useShadowedState } from '../hooks/useShadowedState'; import { paddingRightClass } from './styles'; diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/Seg.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/Seg.tsx index 8a2077b0e66..28b679fd5e3 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/Seg.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/Seg.tsx @@ -6,7 +6,7 @@ import { useAsyncFn } from 'react-use'; import { SelectableValue } from '@grafana/data'; import { AsyncSelect, InlineLabel, Input, Select } from '@grafana/ui'; -import { useShadowedState } from '../../hooks/useShadowedState'; +import { useShadowedState } from '../hooks/useShadowedState'; // this file is a simpler version of `grafana-ui / SegmentAsync.tsx` // with some changes: diff --git a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/VisualInfluxQLEditor.tsx b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/VisualInfluxQLEditor.tsx index 0a00132e9e1..21951edc28a 100644 --- a/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/VisualInfluxQLEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/editor/query/influxql/visual/VisualInfluxQLEditor.tsx @@ -1,9 +1,7 @@ import { css } from '@emotion/css'; import React, { useId, useMemo } from 'react'; -import { useAsync } from 'react-use'; -import { GrafanaTheme2, TypedVariableModel } from '@grafana/data'; -import { getTemplateSrv } from '@grafana/runtime'; +import { GrafanaTheme2 } from '@grafana/data'; import { InlineLabel, SegmentSection, useStyles2 } from '@grafana/ui'; import InfluxDatasource from '../../../../../datasource'; @@ -25,7 +23,11 @@ import { } from '../../../../../queryUtils'; import { InfluxQuery, InfluxQueryTag } from '../../../../../types'; import { DEFAULT_RESULT_FORMAT } from '../../../constants'; +import { useRetentionPolicies } from '../hooks/useRetentionPolicies'; +import { filterTags } from '../utils/filterTags'; import { getNewGroupByPartOptions, getNewSelectPartOptions, makePartList } from '../utils/partListUtils'; +import { withTemplateVariableOptions } from '../utils/withTemplateVariableOptions'; +import { wrapPure, wrapRegex } from '../utils/wrapper'; import { FormatAsSection } from './FormatAsSection'; import { FromSection } from './FromSection'; @@ -41,43 +43,6 @@ type Props = { datasource: InfluxDatasource; }; -function wrapRegex(v: TypedVariableModel): string { - return `/^$${v.name}$/`; -} - -function wrapPure(v: TypedVariableModel): string { - return `$${v.name}`; -} - -function getTemplateVariableOptions(wrapper: (v: TypedVariableModel) => string) { - return ( - getTemplateSrv() - .getVariables() - // we make them regex-params, i'm not 100% sure why. - // probably because this way multi-value variables work ok too. - .map(wrapper) - ); -} - -// helper function to make it easy to call this from the widget-render-code -function withTemplateVariableOptions( - optionsPromise: Promise, - wrapper: (v: TypedVariableModel) => string, - filter?: string -): Promise { - let templateVariableOptions = getTemplateVariableOptions(wrapper); - if (filter) { - templateVariableOptions = templateVariableOptions.filter((tvo) => tvo.indexOf(filter) > -1); - } - return optionsPromise.then((options) => [...templateVariableOptions, ...options]); -} - -// it is possible to add fields into the `InfluxQueryTag` structures, and they do work, -// but in some cases, when we do metadata queries, we have to remove them from the queries. -function filterTags(parts: InfluxQueryTag[], allTagKeys: Set): InfluxQueryTag[] { - return parts.filter((t) => t.key.endsWith('::tag') || allTagKeys.has(t.key + '::tag')); -} - export const VisualInfluxQLEditor = (props: Props): JSX.Element => { const uniqueId = useId(); const formatAsId = `influxdb-qe-format-as-${uniqueId}`; @@ -87,9 +52,7 @@ export const VisualInfluxQLEditor = (props: Props): JSX.Element => { const query = normalizeQuery(props.query); const { datasource } = props; const { measurement, policy } = query; - - const policyData = useAsync(() => getAllPolicies(datasource), [datasource]); - const retentionPolicies = !!policyData.error ? [] : policyData.value ?? []; + const { retentionPolicies } = useRetentionPolicies(datasource); const allTagKeys = useMemo(async () => { const tagKeys = (await getTagKeysForMeasurementAndTags(datasource, [], measurement, policy)).map( diff --git a/public/app/plugins/datasource/influxdb/module.ts b/public/app/plugins/datasource/influxdb/module.ts index da229451278..c293c017d6f 100644 --- a/public/app/plugins/datasource/influxdb/module.ts +++ b/public/app/plugins/datasource/influxdb/module.ts @@ -2,7 +2,7 @@ import { DataSourcePlugin } from '@grafana/data'; import ConfigEditor from './components/editor/config/ConfigEditor'; import { QueryEditor } from './components/editor/query/QueryEditor'; -import InfluxStartPage from './components/editor/query/influxql/InfluxStartPage'; +import { InfluxStartPage } from './components/editor/query/influxql/InfluxStartPage'; import VariableQueryEditor from './components/editor/variable/VariableQueryEditor'; import InfluxDatasource from './datasource'; diff --git a/public/app/plugins/datasource/influxdb/specs/mocks.ts b/public/app/plugins/datasource/influxdb/specs/mocks.ts index 9402f08aa44..72c01d4453a 100644 --- a/public/app/plugins/datasource/influxdb/specs/mocks.ts +++ b/public/app/plugins/datasource/influxdb/specs/mocks.ts @@ -58,6 +58,6 @@ export function getMockDSInstanceSettings(): DataSourceInstanceSettings Date: Fri, 9 Jun 2023 14:22:35 +0200 Subject: [PATCH 08/24] LogsPanel: Remove top margin (#69847) * LogsPanel: Remove top margin * Fixing --- public/app/plugins/panel/logs/LogsPanel.tsx | 39 +++++++++++---------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/public/app/plugins/panel/logs/LogsPanel.tsx b/public/app/plugins/panel/logs/LogsPanel.tsx index 3aff98323e9..85ab80ae0b5 100644 --- a/public/app/plugins/panel/logs/LogsPanel.tsx +++ b/public/app/plugins/panel/logs/LogsPanel.tsx @@ -1,4 +1,4 @@ -import { css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import React, { useCallback, useMemo, useRef, useLayoutEffect, useState } from 'react'; import { @@ -42,7 +42,7 @@ export const LogsPanel = ({ id, }: LogsPanelProps) => { const isAscending = sortOrder === LogsSortOrder.Ascending; - const style = useStyles2(getStyles(title, isAscending)); + const style = useStyles2(getStyles); const [scrollTop, setScrollTop] = useState(0); const logsContainerRef = useRef(null); @@ -95,7 +95,7 @@ export const LogsPanel = ({ } const renderCommonLabels = () => ( -
+
Common labels:
@@ -127,20 +127,21 @@ export const LogsPanel = ({ ); }; -const getStyles = (title: string, isAscending: boolean) => (theme: GrafanaTheme2) => ({ - container: css` - margin-bottom: ${theme.spacing(1.5)}; - //We can remove this hot-fix when we fix panel menu with no title overflowing top of all panels - margin-top: ${theme.spacing(!title ? 2.5 : 0)}; - `, - labelContainer: css` - margin: ${isAscending ? theme.spacing(0.5, 0, 0.5, 0) : theme.spacing(0, 0, 0.5, 0.5)}; - display: flex; - align-items: center; - `, - label: css` - margin-right: ${theme.spacing(0.5)}; - font-size: ${theme.typography.bodySmall.fontSize}; - font-weight: ${theme.typography.fontWeightMedium}; - `, +const getStyles = (theme: GrafanaTheme2) => ({ + container: css({ + marginBottom: theme.spacing(1.5), + }), + labelContainer: css({ + margin: theme.spacing(0, 0, 0.5, 0.5), + display: 'flex', + alignItems: 'center', + }), + labelContainerAscending: css({ + margin: theme.spacing(0.5, 0, 0.5, 0), + }), + label: css({ + marginRight: theme.spacing(0.5), + fontSize: theme.typography.bodySmall.fontSize, + fontWeight: theme.typography.fontWeightMedium, + }), }); From c731d9fe2c62529da046c3442f01d64832e51362 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Fri, 9 Jun 2023 15:26:32 +0200 Subject: [PATCH 09/24] Authentication UI: Add metric for the first usage (#69779) --- public/app/features/auth-config/AuthConfigPage.tsx | 8 ++++++++ .../features/auth-config/components/ConfigureAuthCTA.tsx | 3 +++ 2 files changed, 11 insertions(+) diff --git a/public/app/features/auth-config/AuthConfigPage.tsx b/public/app/features/auth-config/AuthConfigPage.tsx index 2628ef2c599..388181e2aa3 100644 --- a/public/app/features/auth-config/AuthConfigPage.tsx +++ b/public/app/features/auth-config/AuthConfigPage.tsx @@ -4,6 +4,7 @@ import React, { useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { GrafanaTheme2 } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { StoreState } from 'app/types'; @@ -63,7 +64,13 @@ export const AuthConfigPageUnconnected = ({ providerStatuses, isLoading, loadSet documentation. ); + const subTitle = Manage your auth settings and configure single sign-on. Find out more in our {docsLink}; + + const onCTAClick = () => { + reportInteraction('authentication_ui_created', { provider: firstAvailableProvider?.type }); + }; + return ( @@ -92,6 +99,7 @@ export const AuthConfigPageUnconnected = ({ providerStatuses, isLoading, loadSet description={`Important: if you have ${firstAvailableProvider.type} configuration enabled via the .ini file Grafana is using it. Configuring ${firstAvailableProvider.type} via UI will take precedence over any configuration in the .ini file. No changes will be written into .ini file.`} + onClick={onCTAClick} /> )} {!!configuresProviders?.length && ( diff --git a/public/app/features/auth-config/components/ConfigureAuthCTA.tsx b/public/app/features/auth-config/components/ConfigureAuthCTA.tsx index 78892b0d874..fca98251f28 100644 --- a/public/app/features/auth-config/components/ConfigureAuthCTA.tsx +++ b/public/app/features/auth-config/components/ConfigureAuthCTA.tsx @@ -12,6 +12,7 @@ export interface Props { buttonTitle: string; buttonDisabled?: boolean; description?: string; + onClick?: () => void; } const ConfigureAuthCTA: React.FunctionComponent = ({ @@ -21,6 +22,7 @@ const ConfigureAuthCTA: React.FunctionComponent = ({ buttonTitle, buttonDisabled, description, + onClick, }) => { const styles = useStyles2(getStyles); const footer = description ? {description} : ''; @@ -34,6 +36,7 @@ const ConfigureAuthCTA: React.FunctionComponent = ({ className={ctaElementClassName} data-testid={selectors.components.CallToActionCard.buttonV2(buttonTitle)} disabled={buttonDisabled} + onClick={() => onClick && onClick()} > {buttonTitle} From 840e8d977236ecbe5abc2bc169653e0566f72a3b Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 9 Jun 2023 14:32:30 +0100 Subject: [PATCH 10/24] docs: update list on new detections (#69761) * docs: update list on new detections * docs: remove updated plugins, formatting * re-add Oracle plugins --- .../angular_deprecation/angular-plugins.md | 74 ++++++++++++++----- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/docs/sources/developers/angular_deprecation/angular-plugins.md b/docs/sources/developers/angular_deprecation/angular-plugins.md index 28b5509e59d..41272189af0 100644 --- a/docs/sources/developers/angular_deprecation/angular-plugins.md +++ b/docs/sources/developers/angular_deprecation/angular-plugins.md @@ -41,10 +41,30 @@ Guidance on migrating a plugin to React can be found in our [migration guide]({{ ## Apps +### [BelugaCDN](https://grafana.com/grafana/plugins/belugacdn-app) + +Latest Version: 1.2.1 | Signature: Commercial | Last Updated: 2023 + +> [Migration issue](https://github.com/belugacdn/grafana-belugacdn-app/issues/7) has been raised. + +> **Warning:** Lack of recent activity in the [project repository](https://github.com/belugacdn/grafana-belugacdn-app) in the past 7 years suggests project _may_ not be actively maintained. + +### [Bosun](https://grafana.com/grafana/plugins/bosun-app) + +Latest Version: 0.0.29 | Signature: Community | Last Updated: 2023 + +> [Migration issue](https://github.com/bosun-monitor/bosun-grafana-app/issues/63) has been raised. + ### [Cloudflare Grafana App](https://grafana.com/grafana/plugins/cloudflare-app/) Latest Version: 0.2.4 | Signature: Commercial | Last Updated: 2022 +### [GLPI](https://grafana.com/grafana/plugins/ddurieux-glpi-app) + +Latest Version: 1.3.1 | Signature: Community | Last Updated: 2021 + +> [Migration issue](https://github.com/ddurieux/glpi_app_grafana/issues/96) has been raised. + ### [DevOpsProdigy KubeGraf](https://grafana.com/grafana/plugins/devopsprodigy-kubegraf-app/) Latest Version: 1.5.2 | Signature: Community | Last Updated: 2021 @@ -53,10 +73,46 @@ Latest Version: 1.5.2 | Signature: Community | Last Updated: 2021 > **Migration available - potential alternative:** Grafana Cloud includes a [Kubernetes integration](https://grafana.com/solutions/kubernetes/). +### [AWS IoT TwinMaker App](https://grafana.com/grafana/plugins/grafana-iot-twinmaker-app) + +Latest Version: 1.6.2 | Signature: Commercial | Last Updated: 2023 + +> **Note:** Plugin should continue to work even if Angular is disabled, and a full removal of Angular related code is planned. + ### [Kentik Connect Pro](https://grafana.com/grafana/plugins/kentik-connect-app/) Latest Version: 1.6.2 | Signature: Commercial | Last Updated: 2023 +### [Moogsoft AIOps](https://grafana.com/grafana/plugins/moogsoft-aiops-app) + +Latest Version: 8.0.2 | Signature: Commercial | Last Updated: 2022 + +### [OpenNMS Helm](https://grafana.com/grafana/plugins/opennms-helm-app) + +Latest Version: 8.0.4 | Signature: Community | Last Updated: 2023 + +> **Migration available - plugin superseded:** The plugin has effectively been replaced with a [new plugin](https://grafana.com/grafana/plugins/opennms-opennms-app/) based on React. + +### [Percona](https://grafana.com/grafana/plugins/percona-percona-app/) + +Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 + +> **Warning:** [Project repository](https://github.com/percona/grafana-app) was archived on June 12, 2020. + +### [Stagemonitor Elasticsearch](https://grafana.com/grafana/plugins/stagemonitor-elasticsearch-app) + +Latest Version: 0.83.3 | Signature: Community | Last Updated: 2021 + +> [Migration issue](https://github.com/stagemonitor/stagemonitor-grafana-elasticsearch/issues/1) has been raised. + +> **Warning:** Lack of recent activity in the [project repository](https://github.com/stagemonitor/stagemonitor-grafana-elasticsearch) in the past 4 years suggests project _may_ not be actively maintained. + +### [Voxter VoIP Platform Metrics](https://grafana.com/grafana/plugins/voxter-app) + +Latest Version: 0.0.2 | Signature: Community | Last Updated: 2021 + +> **Warning:** Lack of recent activity in the [project repository](https://github.com/raintank/voxter-app) in the past 3 years suggests project _may_ not be actively maintained. + ## Datasources ### [Druid](https://grafana.com/grafana/plugins/abhisant-druid-datasource/) @@ -103,10 +159,6 @@ Latest Version: 2.2.3 | Signature: Community | Last Updated: 2022 > **Warning:** Lack of recent activity in the [project repository](https://github.com/chaos-mesh/datasource) in the past year suggests project _may_ not be actively maintained. -### [Cognite Data Fusion](https://grafana.com/grafana/plugins/cognitedata-datasource/) - -Latest Version: 3.0.0 | Signature: Commercial | Last Updated: 2023 - ### [DeviceHive](https://grafana.com/grafana/plugins/devicehive-devicehive-datasource/) Latest Version: 2.0.2 | Signature: Community | Last Updated: 2021 @@ -185,12 +237,6 @@ Latest Version: 1.4.2 | Signature: Grafana | Last Updated: 2021 > **Note:** If you're looking for an example of a data source plugin to start from, refer to [grafana-starter-datasource-backend](https://github.com/grafana/grafana-starter-datasource-backend). -### [Splunk](https://grafana.com/grafana/plugins/grafana-splunk-datasource/) - -Latest Version: 4.1.6 | Signature: Grafana | Last Updated: 2023 - -> **Note:** Removal of any angular dependency is on the near term roadmap. - ### [Strava](https://grafana.com/grafana/plugins/grafana-strava-datasource/) Latest Version: 1.5.1 | Signature: Grafana | Last Updated: 2022 @@ -203,12 +249,6 @@ Latest Version: 1.0.3 | Signature: Community | Last Updated: 2021 > **Warning:** Lack of recent activity in the [project repository](https://github.com/GridProtectionAlliance/openHistorian-grafana/) in the past 2 years suggests project _may_ not be actively maintained. -### [OSIsoft-PI](https://grafana.com/grafana/plugins/gridprotectionalliance-osisoftpi-datasource/) - -Latest Version: 3.1.0 | Signature: Community | Last Updated: 2023 - -> **Note:** Fixed in 4.0.0 which should be published soon - [source](https://github.com/GridProtectionAlliance/osisoftpi-grafana/issues/119#issuecomment-1493566212). - ### [Hawkular](https://grafana.com/grafana/plugins/hawkular-datasource/) Latest Version: 1.1.2 | Signature: Community | Last Updated: 2021 @@ -283,7 +323,7 @@ Latest Version: 3.0.0 | Signature: Commercial | Last Updated: 2023 ### [Oracle Cloud Infrastructure Metrics](https://grafana.com/grafana/plugins/oci-metrics-datasource/) -Latest Version: 4.0.0 | Signature: Commercial | Last Updated: 2023 +Latest Version: 4.0.1 | Signature: Commercial | Last Updated: 2023 ### [Warp 10](https://grafana.com/grafana/plugins/ovh-warp10-datasource/) From ff3e028a8588ab3f37410e44d51a5550744bf291 Mon Sep 17 00:00:00 2001 From: Santiago Date: Fri, 9 Jun 2023 10:59:24 -0300 Subject: [PATCH 11/24] Alerting: Add image URI annotation only when there's an image (#69825) * Alerting: Add image URI annotation only when there's an image * fix function name (changed on main branch) --- pkg/services/ngalert/state/compat.go | 11 +++++++++-- pkg/services/ngalert/state/compat_test.go | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pkg/services/ngalert/state/compat.go b/pkg/services/ngalert/state/compat.go index 70d97e474d8..fbe934bc344 100644 --- a/pkg/services/ngalert/state/compat.go +++ b/pkg/services/ngalert/state/compat.go @@ -49,7 +49,10 @@ func StateToPostableAlert(alertState *State, appURL *url.URL) *models.PostableAl } if alertState.Image != nil { - nA[alertingModels.ImageTokenAnnotation] = generateImageURI(alertState.Image) + imageURI := generateImageURI(alertState.Image) + if imageURI != "" { + nA[alertingModels.ImageTokenAnnotation] = imageURI + } } if alertState.StateReason != "" { @@ -174,5 +177,9 @@ func generateImageURI(image *ngModels.Image) string { if image.URL != "" { return image.URL } - return "token://" + image.Token + if image.Token != "" { + return "token://" + image.Token + } + + return "" } diff --git a/pkg/services/ngalert/state/compat_test.go b/pkg/services/ngalert/state/compat_test.go index a33551cc27f..f98f32ff7a1 100644 --- a/pkg/services/ngalert/state/compat_test.go +++ b/pkg/services/ngalert/state/compat_test.go @@ -133,6 +133,21 @@ func Test_StateToPostableAlert(t *testing.T) { require.Equal(t, expected, result.Annotations) }) + + t.Run("don't add __alertImageToken__ if there's no image token", func(t *testing.T) { + alertState := randomState(tc.state) + alertState.Annotations = randomMapOfStrings() + alertState.Image = &ngModels.Image{} + + result := StateToPostableAlert(alertState, appURL) + + expected := make(models.LabelSet, len(alertState.Annotations)+1) + for k, v := range alertState.Annotations { + expected[k] = v + } + + require.Equal(t, expected, result.Annotations) + }) }) t.Run("should add state reason annotation if not empty", func(t *testing.T) { From a5b9eac88ef4bee1487baa11e1682fa00d17605e Mon Sep 17 00:00:00 2001 From: Ibrahim <93064150+IbrahimCSAE@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:57:56 -0400 Subject: [PATCH 12/24] Transformations: Config overrides being lost when config from query transform is applied (#69720) fix config overides being lost by transforms --- .../features/transformers/configFromQuery/configFromQuery.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/transformers/configFromQuery/configFromQuery.ts b/public/app/features/transformers/configFromQuery/configFromQuery.ts index 5b3bc7cb2c6..0ac2fc25788 100644 --- a/public/app/features/transformers/configFromQuery/configFromQuery.ts +++ b/public/app/features/transformers/configFromQuery/configFromQuery.ts @@ -66,6 +66,7 @@ export function extractConfigFromQuery(options: ConfigFromQueryTransformOptions, const outputFrame: DataFrame = { fields: [], length: frame.length, + refId: frame.refId, }; for (const field of frame.fields) { @@ -85,7 +86,6 @@ export function extractConfigFromQuery(options: ConfigFromQueryTransformOptions, output.push(outputFrame); } - return output; } From ca8d0ef041d65e77d929e340d93fe48f6434fc1c Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 9 Jun 2023 16:00:16 +0100 Subject: [PATCH 13/24] NestedFolders: Move `New folder` into a drawer (#69706) * make New folder a drawer * use sentence case * extract strings and update tests * use sm drawer --- .../BrowseDashboardsPage.tsx | 5 +- .../components/CreateNewButton.test.tsx | 39 ++++++++--- .../components/CreateNewButton.tsx | 69 +++++++++++++++---- .../components/NewFolderForm.tsx | 59 ++++++++++++++++ public/app/features/search/tempI18nPhrases.ts | 4 +- public/locales/en-US/grafana.json | 4 +- public/locales/pseudo-LOCALE/grafana.json | 4 +- 7 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 public/app/features/browse-dashboards/components/NewFolderForm.tsx diff --git a/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx b/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx index c67fe825014..e2c1700633c 100644 --- a/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx +++ b/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx @@ -16,7 +16,7 @@ import { skipToken, useGetFolderQuery, useSaveFolderMutation } from './api/brows import { BrowseActions } from './components/BrowseActions/BrowseActions'; import { BrowseFilters } from './components/BrowseFilters'; import { BrowseView } from './components/BrowseView'; -import { CreateNewButton } from './components/CreateNewButton'; +import CreateNewButton from './components/CreateNewButton'; import { FolderActionsButton } from './components/FolderActionsButton'; import { SearchView } from './components/SearchView'; import { getFolderPermissions } from './permissions'; @@ -104,7 +104,8 @@ const BrowseDashboardsPage = memo(({ match }: Props) => { {folderDTO && } {(canCreateDashboards || canCreateFolder) && ( diff --git a/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx b/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx index d81b3818161..d5811f9903d 100644 --- a/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx +++ b/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx @@ -1,11 +1,16 @@ -import { render, screen } from '@testing-library/react'; +import { render as rtlRender, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; +import { TestProvider } from 'test/helpers/TestProvider'; -import { CreateNewButton } from './CreateNewButton'; +import CreateNewButton from './CreateNewButton'; + +function render(...[ui, options]: Parameters) { + rtlRender({ui}, options); +} async function renderAndOpen(folderUID?: string) { - render(); + render(); const newButton = screen.getByText('New'); await userEvent.click(newButton); } @@ -14,27 +19,39 @@ describe('NewActionsButton', () => { it('should display the correct urls with a given folderUID', async () => { await renderAndOpen('123'); - expect(screen.getByText('New Dashboard')).toHaveAttribute('href', '/dashboard/new?folderUid=123'); - expect(screen.getByText('New Folder')).toHaveAttribute('href', '/dashboards/folder/new?folderUid=123'); + expect(screen.getByText('New dashboard')).toHaveAttribute('href', '/dashboard/new?folderUid=123'); expect(screen.getByText('Import')).toHaveAttribute('href', '/dashboard/import?folderUid=123'); }); it('should display urls without params when there is no folderUID', async () => { await renderAndOpen(); - expect(screen.getByText('New Dashboard')).toHaveAttribute('href', '/dashboard/new'); - expect(screen.getByText('New Folder')).toHaveAttribute('href', '/dashboards/folder/new'); + expect(screen.getByText('New dashboard')).toHaveAttribute('href', '/dashboard/new'); expect(screen.getByText('Import')).toHaveAttribute('href', '/dashboard/import'); }); + it('clicking the "New folder" button opens the drawer', async () => { + const mockParentFolderTitle = 'mockParentFolderTitle'; + render(); + + const newButton = screen.getByText('New'); + await userEvent.click(newButton); + await userEvent.click(screen.getByText('New folder')); + + const drawer = screen.getByRole('dialog', { name: 'Drawer title New folder' }); + expect(drawer).toBeInTheDocument(); + expect(within(drawer).getByRole('heading', { name: 'New folder' })).toBeInTheDocument(); + expect(within(drawer).getByText(`Location: ${mockParentFolderTitle}`)).toBeInTheDocument(); + }); + it('should only render dashboard items when folder creation is disabled', async () => { render(); const newButton = screen.getByText('New'); await userEvent.click(newButton); - expect(screen.getByText('New Dashboard')).toBeInTheDocument(); + expect(screen.getByText('New dashboard')).toBeInTheDocument(); expect(screen.getByText('Import')).toBeInTheDocument(); - expect(screen.queryByText('New Folder')).not.toBeInTheDocument(); + expect(screen.queryByText('New folder')).not.toBeInTheDocument(); }); it('should only render folder item when dashboard creation is disabled', async () => { @@ -42,8 +59,8 @@ describe('NewActionsButton', () => { const newButton = screen.getByText('New'); await userEvent.click(newButton); - expect(screen.queryByText('New Dashboard')).not.toBeInTheDocument(); + expect(screen.queryByText('New dashboard')).not.toBeInTheDocument(); expect(screen.queryByText('Import')).not.toBeInTheDocument(); - expect(screen.getByText('New Folder')).toBeInTheDocument(); + expect(screen.getByText('New folder')).toBeInTheDocument(); }); }); diff --git a/public/app/features/browse-dashboards/components/CreateNewButton.tsx b/public/app/features/browse-dashboards/components/CreateNewButton.tsx index c1757a4a744..6d9b1367313 100644 --- a/public/app/features/browse-dashboards/components/CreateNewButton.tsx +++ b/public/app/features/browse-dashboards/components/CreateNewButton.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; +import { connect, ConnectedProps } from 'react-redux'; -import { Button, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui'; +import { Button, Drawer, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui'; +import { createNewFolder } from 'app/features/folders/state/actions'; import { getNewDashboardPhrase, getNewFolderPhrase, @@ -8,41 +10,78 @@ import { getNewPhrase, } from 'app/features/search/tempI18nPhrases'; -interface Props { +import { NewFolderForm } from './NewFolderForm'; + +const mapDispatchToProps = { + createNewFolder, +}; + +const connector = connect(null, mapDispatchToProps); + +interface OwnProps { + parentFolderTitle?: string; /** * Pass a folder UID in which the dashboard or folder will be created */ - inFolder?: string; + parentFolderUid?: string; canCreateFolder: boolean; canCreateDashboard: boolean; } -export function CreateNewButton({ inFolder, canCreateDashboard, canCreateFolder }: Props) { +type Props = OwnProps & ConnectedProps; + +function CreateNewButton({ + parentFolderTitle, + parentFolderUid, + canCreateDashboard, + canCreateFolder, + createNewFolder, +}: Props) { const [isOpen, setIsOpen] = useState(false); + const [showNewFolderDrawer, setShowNewFolderDrawer] = useState(false); + + const onCreateFolder = (folderName: string) => { + createNewFolder(folderName, parentFolderUid); + setShowNewFolderDrawer(false); + }; + const newMenu = ( {canCreateDashboard && ( - - )} - {canCreateFolder && ( - + )} + {canCreateFolder && setShowNewFolderDrawer(true)} label={getNewFolderPhrase()} />} {canCreateDashboard && ( - + )} ); return ( - - - + <> + + + + {showNewFolderDrawer && ( + setShowNewFolderDrawer(false)} + size="sm" + > + setShowNewFolderDrawer(false)} /> + + )} + ); } +export default connector(CreateNewButton); + /** * * @param url without any parameters diff --git a/public/app/features/browse-dashboards/components/NewFolderForm.tsx b/public/app/features/browse-dashboards/components/NewFolderForm.tsx new file mode 100644 index 00000000000..9a426df9d1a --- /dev/null +++ b/public/app/features/browse-dashboards/components/NewFolderForm.tsx @@ -0,0 +1,59 @@ +import React from 'react'; + +import { Button, Input, Form, Field, HorizontalGroup } from '@grafana/ui'; + +import { validationSrv } from '../../manage-dashboards/services/ValidationSrv'; + +interface Props { + onConfirm: (folderName: string) => void; + onCancel: () => void; +} + +interface FormModel { + folderName: string; +} + +const initialFormModel: FormModel = { folderName: '' }; + +export function NewFolderForm({ onCancel, onConfirm }: Props) { + const validateFolderName = async (folderName: string) => { + try { + await validationSrv.validateNewFolderName(folderName); + return true; + } catch (e) { + if (e instanceof Error) { + return e.message; + } else { + throw e; + } + } + }; + + return ( +
onConfirm(form.folderName)}> + {({ register, errors }) => ( + <> + + await validateFolderName(v), + })} + /> + + + + + + + )} +
+ ); +} diff --git a/public/app/features/search/tempI18nPhrases.ts b/public/app/features/search/tempI18nPhrases.ts index 83b99bf2570..40c276270ae 100644 --- a/public/app/features/search/tempI18nPhrases.ts +++ b/public/app/features/search/tempI18nPhrases.ts @@ -10,11 +10,11 @@ export function getSearchPlaceholder(includePanels = false) { } export function getNewDashboardPhrase() { - return t('search.dashboard-actions.new-dashboard', 'New Dashboard'); + return t('search.dashboard-actions.new-dashboard', 'New dashboard'); } export function getNewFolderPhrase() { - return t('search.dashboard-actions.new-folder', 'New Folder'); + return t('search.dashboard-actions.new-folder', 'New folder'); } export function getImportPhrase() { diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 920c860799c..f789b63014b 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -408,8 +408,8 @@ "dashboard-actions": { "import": "Import", "new": "New", - "new-dashboard": "New Dashboard", - "new-folder": "New Folder" + "new-dashboard": "New dashboard", + "new-folder": "New folder" }, "folder-view": { "go-to-folder": "Go to folder", diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json index bbfc8c0ab83..f0f3b927701 100644 --- a/public/locales/pseudo-LOCALE/grafana.json +++ b/public/locales/pseudo-LOCALE/grafana.json @@ -408,8 +408,8 @@ "dashboard-actions": { "import": "Ĩmpőřŧ", "new": "Ńęŵ", - "new-dashboard": "Ńęŵ Đäşĥþőäřđ", - "new-folder": "Ńęŵ Főľđęř" + "new-dashboard": "Ńęŵ đäşĥþőäřđ", + "new-folder": "Ńęŵ ƒőľđęř" }, "folder-view": { "go-to-folder": "Ğő ŧő ƒőľđęř", From 516baf59fba37d277e284c34bbfdc399d179b50b Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Fri, 9 Jun 2023 18:21:32 +0300 Subject: [PATCH 14/24] StyleGuide: Add testing guide (#69403) * StyleGuide: Testing Select * Add mocking section * Fixes * Add examples of backendSrv mocks * Minor tweaks * Updates after review * Update examples --- contribute/style-guides/testing.md | 225 ++++++++++++++++++ .../core/components/Select/OrgPicker.test.tsx | 48 ++++ .../app/core/components/Select/OrgPicker.tsx | 2 +- 3 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 contribute/style-guides/testing.md create mode 100644 public/app/core/components/Select/OrgPicker.test.tsx diff --git a/contribute/style-guides/testing.md b/contribute/style-guides/testing.md new file mode 100644 index 00000000000..7ca50d926b9 --- /dev/null +++ b/contribute/style-guides/testing.md @@ -0,0 +1,225 @@ +# Testing Guidelines + +The goal of this document is to address the most frequently asked "How to" questions related to unit testing. + +## Best practices + +- Default to the `*ByRole` queries when testing components as it encourages testing with accessibility concerns in mind. It's also possible to use `*ByLabelText` queries. However, the `*ByRole` queries are [more robust](https://testing-library.com/docs/queries/bylabeltext/#name) and are generally recommended over the former. + +## Testing User Interactions + +We use the [user-event](https://testing-library.com/docs/user-event/intro) library for simulating user interactions during testing. This library is preferred over the built-in `fireEvent` method, as it more accurately mirrors real user interactions with elements. + +There are two important considerations when working with `userEvent`: + +1. All methods in `userEvent` are asynchronous, and thus require the use of `await` when called. +2. Directly calling methods from `userEvent` may not be supported in future versions. As such, it's necessary to first call `userEvent.setup()` prior to the tests. This method returns a `userEvent` instance, complete with all its methods. This setup process can be simplified using a utility function: + +```tsx +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +function setup(jsx: JSX.Element) { + return { + user: userEvent.setup(), + ...render(jsx), + }; +} + +it('should render', async () => { + const { user } = setup(