[v9.0.x] AzureMonitor: Update UI to experimental package (#52235)

* AzureMonitor: Update UI to experimental package (#52123)

* feat: make azure experimental the default

* feat: combine metrics query editor rows

fix: linter errors

* chore: remove test loop for DimensionFields test

(cherry picked from commit 5d199a40b7)

* chore: update .betterer

Co-authored-by: Adam Simpson <adam@adamsimpson.net>
This commit is contained in:
Grot (@grafanabot)
2022-07-14 14:01:33 +00:00
committed by GitHub
co-authored by Adam Simpson
parent 54b8bee3cc
commit 9be6d854d9
19 changed files with 770 additions and 1701 deletions
+19 -445
View File
@@ -1858,6 +1858,15 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/Portal/Portal.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"packages/grafana-ui/src/components/QueryField/QueryField.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -1874,6 +1883,16 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/SecretInput/SecretInput.story.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/Segment/Segment.story.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"]
],
"packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -3843,9 +3862,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/alerting/TestRuleResult.test.tsx:2358420489": [
[28, 30, 36, "Do not use any type assertions.", "702850259"]
],
"public/app/features/alerting/TestRuleResult.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -3941,9 +3957,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/features/alerting/unified/Receivers.test.tsx:3742116867": [
[143, 34, 29, "Do not use any type assertions.", "2249960884"]
],
"public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -3961,24 +3974,10 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/RuleViewer.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/alerting/unified/Silences.test.tsx:1255403007": [
[108, 32, 29, "Do not use any type assertions.", "2249960884"],
[195, 34, 29, "Do not use any type assertions.", "2249960884"]
],
"public/app/features/alerting/unified/api/alertmanager.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/alerting/unified/api/annotations.test.ts:2579323536": [
[32, 10, 52, "Do not use any type assertions.", "3449840057"],
[33, 10, 52, "Do not use any type assertions.", "3512032697"],
[34, 10, 52, "Do not use any type assertions.", "3809885851"],
[35, 10, 42, "Do not use any type assertions.", "3760318175"],
[49, 10, 52, "Do not use any type assertions.", "3449840057"],
[50, 10, 52, "Do not use any type assertions.", "865105467"],
[51, 10, 52, "Do not use any type assertions.", "2729874170"],
[52, 10, 52, "Do not use any type assertions.", "3718693118"]
],
"public/app/features/alerting/unified/api/buildInfo.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -4059,9 +4058,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/ConditionField.test.tsx:3255434476": [
[17, 25, 255, "Do not use any type assertions.", "445528897"]
],
"public/app/features/alerting/unified/components/rule-editor/ExpressionEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -4074,19 +4070,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/AlertType.test.tsx:2143187355": [
[41, 10, 29, "Do not use any type assertions.", "2249960884"],
[54, 72, 29, "Do not use any type assertions.", "2249960884"],
[66, 65, 29, "Do not use any type assertions.", "2249960884"]
],
"public/app/features/alerting/unified/components/rule-editor/util.test.ts:115971189": [
[101, 25, 42, "Do not use any type assertions.", "3490778927"],
[114, 25, 42, "Do not use any type assertions.", "3490778927"],
[123, 25, 42, "Do not use any type assertions.", "3490778927"],
[131, 25, 42, "Do not use any type assertions.", "3490778927"],
[139, 13, 42, "Do not use any type assertions.", "3490778927"],
[140, 13, 42, "Do not use any type assertions.", "3394454764"]
],
"public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -4103,13 +4086,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/silences/SilencesFilter.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts:3536006768": [
[7, 28, 87, "Do not use any type assertions.", "3058961128"],
[12, 28, 97, "Do not use any type assertions.", "4219061192"],
[18, 19, 105, "Do not use any type assertions.", "3168271890"],
[23, 19, 105, "Do not use any type assertions.", "1620836241"],
[40, 18, 51, "Do not use any type assertions.", "107010128"]
],
"public/app/features/alerting/unified/hooks/useControlledFieldArray.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -4122,9 +4098,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/features/alerting/unified/hooks/useIsRuleEditable.test.tsx:4024141754": [
[150, 64, 29, "Do not use any type assertions.", "2249960884"]
],
"public/app/features/alerting/unified/mocks.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -4139,14 +4112,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Do not use any type assertions.", "11"]
],
"public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts:838848248": [
[219, 9, 81, "Do not use any type assertions.", "1125692145"],
[219, 9, 67, "Do not use any type assertions.", "4033275024"],
[226, 9, 78, "Do not use any type assertions.", "3342662942"],
[226, 9, 61, "Do not use any type assertions.", "291326006"],
[234, 6, 172, "Do not use any type assertions.", "1154786841"],
[242, 6, 177, "Do not use any type assertions.", "3855113404"]
],
"public/app/features/alerting/unified/state/actions.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -4169,10 +4134,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/alerting/unified/utils/query.test.ts:4173083967": [
[55, 16, 16, "Do not use any type assertions.", "1747412709"],
[56, 20, 24, "Do not use any type assertions.", "3254438164"]
],
"public/app/features/alerting/unified/utils/receiver-form.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -4204,20 +4165,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"]
],
"public/app/features/alerting/unified/utils/timeRange.test.ts:960501818": [
[15, 17, 248, "Do not use any type assertions.", "1101398068"],
[32, 41, 40, "Do not use any type assertions.", "4073243510"],
[43, 17, 342, "Do not use any type assertions.", "2705074487"],
[70, 41, 40, "Do not use any type assertions.", "4073243510"],
[83, 15, 191, "Do not use any type assertions.", "676893829"],
[100, 39, 40, "Do not use any type assertions.", "4073243510"],
[108, 15, 207, "Do not use any type assertions.", "3256955732"],
[134, 34, 40, "Do not use any type assertions.", "4073243510"],
[145, 15, 214, "Do not use any type assertions.", "2540635293"],
[165, 39, 40, "Do not use any type assertions.", "4073243510"],
[178, 15, 221, "Do not use any type assertions.", "1204635877"],
[198, 39, 40, "Do not use any type assertions.", "4073243510"]
],
"public/app/features/annotations/components/AnnotationResultMapper.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -4490,15 +4437,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"]
],
"public/app/features/dashboard/components/PanelEditor/state/selectors.test.ts:314488950": [
[20, 41, 48, "Do not use any type assertions.", "1149044184"],
[24, 43, 49, "Do not use any type assertions.", "2553364371"],
[51, 51, 82, "Do not use any type assertions.", "1958885332"],
[62, 51, 82, "Do not use any type assertions.", "531303526"],
[80, 51, 82, "Do not use any type assertions.", "1958885332"],
[99, 51, 82, "Do not use any type assertions.", "1958885332"],
[112, 51, 82, "Do not use any type assertions.", "1958885332"]
],
"public/app/features/dashboard/components/PanelEditor/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -4587,19 +4525,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/dashboard/components/ShareModal/SharePublicDashboardUtils.test.tsx:3549968113": [
[24, 18, 46, "Do not use any type assertions.", "2293567025"],
[31, 18, 38, "Do not use any type assertions.", "1524369398"],
[36, 18, 30, "Do not use any type assertions.", "387012726"],
[38, 14, 21, "Do not use any type assertions.", "3316176532"]
],
"public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard/components/ShareModal/utils.test.ts:3192556439": [
[34, 31, 115, "Do not use any type assertions.", "3780428905"],
[34, 31, 102, "Do not use any type assertions.", "1055478161"]
],
"public/app/features/dashboard/components/ShareModal/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -4657,10 +4585,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/dashboard/components/VersionHistory/utils.test.ts:3825537265": [
[127, 25, 23, "Do not use any type assertions.", "926140717"],
[127, 25, 15, "Do not use any type assertions.", "1238655602"]
],
"public/app/features/dashboard/components/VersionHistory/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -5348,10 +5272,6 @@ exports[`better eslint`] = {
"public/app/features/expressions/guards.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/folders/FolderSettingsPage.test.tsx:1109052730": [
[13, 14, 14, "Do not use any type assertions.", "3112983303"],
[36, 19, 40, "Do not use any type assertions.", "2693764194"]
],
"public/app/features/folders/state/actions.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -5388,25 +5308,12 @@ exports[`better eslint`] = {
"public/app/features/geo/utils/frameVectorSource.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/geo/utils/location.test.ts:3751297173": [
[30, 61, 10, "Do not use any type assertions.", "525921067"],
[56, 53, 10, "Do not use any type assertions.", "525921067"]
],
"public/app/features/inspector/InspectDataOptions.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"]
],
"public/app/features/inspector/InspectDataTab.test.tsx:4201756100": [
[41, 9, 83, "Do not use any type assertions.", "1478605180"],
[70, 27, 465, "Do not use any type assertions.", "1173398047"],
[70, 27, 450, "Do not use any type assertions.", "1966040902"],
[92, 29, 2029, "Do not use any type assertions.", "1162974715"],
[92, 29, 2014, "Do not use any type assertions.", "701279586"],
[150, 23, 339, "Do not use any type assertions.", "1654092041"],
[150, 23, 324, "Do not use any type assertions.", "1057375888"]
],
"public/app/features/inspector/InspectDataTab.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -5577,10 +5484,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/features/org/OrgDetailsPage.test.tsx:351096404": [
[41, 18, 18, "Do not use any type assertions.", "1715686858"],
[42, 14, 125, "Do not use any type assertions.", "795479886"]
],
"public/app/features/org/state/actions.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -5656,10 +5559,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"public/app/features/playlist/PlaylistForm.test.tsx:2574850033": [
[16, 19, 53, "Do not use any type assertions.", "778424295"],
[16, 19, 41, "Do not use any type assertions.", "3698800435"]
],
"public/app/features/playlist/PlaylistNewPage.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -5668,10 +5567,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"public/app/features/playlist/PlaylistPage.test.tsx:1746955973": [
[12, 6, 59, "Do not use any type assertions.", "3685154675"],
[12, 6, 49, "Do not use any type assertions.", "1184085652"]
],
"public/app/features/playlist/PlaylistSrv.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -5733,16 +5628,6 @@ exports[`better eslint`] = {
"public/app/features/plugins/admin/guards.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/plugins/admin/helpers.test.ts:2922381373": [
[114, 37, 80, "Do not use any type assertions.", "1510435013"],
[116, 35, 82, "Do not use any type assertions.", "3449275506"],
[118, 35, 83, "Do not use any type assertions.", "514649711"],
[126, 31, 57, "Do not use any type assertions.", "472410664"],
[127, 34, 54, "Do not use any type assertions.", "683862165"],
[134, 25, 51, "Do not use any type assertions.", "2457260600"],
[135, 28, 52, "Do not use any type assertions.", "963107955"],
[177, 42, 56, "Do not use any type assertions.", "2128061450"]
],
"public/app/features/plugins/admin/helpers.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -5858,11 +5743,6 @@ exports[`better eslint`] = {
"public/app/features/profile/state/reducers.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/query/components/QueryEditorRow.test.ts:4201471442": [
[7, 9, 60, "Do not use any type assertions.", "155833034"],
[50, 22, 101, "Do not use any type assertions.", "3734235969"],
[50, 22, 88, "Do not use any type assertions.", "3757401717"]
],
"public/app/features/query/components/QueryEditorRow.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -6029,12 +5909,6 @@ exports[`better eslint`] = {
"public/app/features/search/hooks/useDashboardSearch.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/search/hooks/useManageDashboards.test.ts:3293235715": [
[31, 45, 41, "Do not use any type assertions.", "3856094708"],
[31, 45, 15, "Do not use any type assertions.", "363922340"],
[33, 43, 31, "Do not use any type assertions.", "2087413285"],
[33, 43, 13, "Do not use any type assertions.", "2146830713"]
],
"public/app/features/search/hooks/useSearchKeyboardSelection.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -6164,30 +6038,13 @@ 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/features/teams/CreateTeam.test.tsx:136903941": [
[30, 14, 34, "Do not use any type assertions.", "463003776"]
],
"public/app/features/teams/TeamGroupSync.test.tsx:2647720693": [
[12, 12, 17, "Do not use any type assertions.", "2242876437"]
],
"public/app/features/teams/TeamGroupSync.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/teams/TeamList.test.tsx:2054736348": [
[22, 14, 123, "Do not use any type assertions.", "695951401"],
[30, 11, 12, "Do not use any type assertions.", "1079483306"],
[40, 18, 59, "Do not use any type assertions.", "25768610"],
[67, 24, 77, "Do not use any type assertions.", "361803129"],
[84, 24, 77, "Do not use any type assertions.", "1295202722"]
],
"public/app/features/teams/TeamMemberRow.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/teams/TeamMembers.test.tsx:1775840321": [
[31, 13, 18, "Do not use any type assertions.", "2776323642"],
[37, 18, 101, "Do not use any type assertions.", "3599690898"]
],
"public/app/features/teams/TeamMembers.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -6205,15 +6062,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/features/teams/state/selectors.test.ts:4215831928": [
[49, 14, 10, "Do not use any type assertions.", "1584692172"],
[52, 16, 17, "Do not use any type assertions.", "2242876437"],
[67, 18, 101, "Do not use any type assertions.", "3599690898"],
[92, 22, 116, "Do not use any type assertions.", "591810489"],
[107, 22, 116, "Do not use any type assertions.", "2211298791"],
[123, 22, 117, "Do not use any type assertions.", "1169409170"],
[138, 22, 117, "Do not use any type assertions.", "1169409170"]
],
"public/app/features/teams/state/selectors.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -6289,9 +6137,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.test.tsx:1060905279": [
[44, 29, 21, "Do not use any type assertions.", "1548027068"]
],
"public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -6333,11 +6178,6 @@ exports[`better eslint`] = {
"public/app/features/transformers/extractFields/fieldExtractors.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.test.tsx:1072197618": [
[50, 29, 21, "Do not use any type assertions.", "1548027068"],
[59, 41, 21, "Do not use any type assertions.", "1548027068"],
[85, 29, 22, "Do not use any type assertions.", "3205041286"]
],
"public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
@@ -6368,10 +6208,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.test.tsx:2876920155": [
[41, 29, 21, "Do not use any type assertions.", "1548027068"],
[55, 29, 21, "Do not use any type assertions.", "1548027068"]
],
"public/app/features/transformers/spatial/SpatialTransformerEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
@@ -6397,14 +6233,6 @@ exports[`better eslint`] = {
"public/app/features/users/UsersActionBar.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/users/UsersListPage.test.tsx:4284943401": [
[27, 14, 119, "Do not use any type assertions.", "1781051572"],
[35, 11, 15, "Do not use any type assertions.", "2789568508"],
[36, 14, 15, "Do not use any type assertions.", "3505843099"]
],
"public/app/features/users/UsersTable.test.tsx:2179189208": [
[19, 11, 15, "Do not use any type assertions.", "2789568508"]
],
"public/app/features/users/__mocks__/userMocks.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -6418,13 +6246,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/variables/adhoc/actions.test.ts:3228657148": [
[194, 52, 14, "Do not use any type assertions.", "3854427458"],
[330, 52, 14, "Do not use any type assertions.", "3854427458"],
[360, 52, 14, "Do not use any type assertions.", "3854427458"],
[509, 9, 160, "Do not use any type assertions.", "3244710120"],
[511, 10, 57, "Do not use any type assertions.", "3447995104"]
],
"public/app/features/variables/adhoc/actions.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -6445,68 +6266,19 @@ exports[`better eslint`] = {
"public/app/features/variables/adhoc/picker/AdHocFilterRenderer.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/variables/adhoc/reducer.test.ts:531962865": [
[25, 16, 147, "Do not use any type assertions.", "2892790792"],
[45, 16, 246, "Do not use any type assertions.", "3920845434"],
[69, 16, 147, "Do not use any type assertions.", "2892790792"],
[90, 16, 147, "Do not use any type assertions.", "771746056"],
[110, 16, 118, "Do not use any type assertions.", "2442568355"],
[112, 21, 27, "Do not use any type assertions.", "37558224"],
[132, 16, 248, "Do not use any type assertions.", "2892427802"],
[157, 16, 248, "Do not use any type assertions.", "3562752889"],
[180, 16, 250, "Do not use any type assertions.", "601750330"],
[202, 16, 250, "Do not use any type assertions.", "601750330"]
],
"public/app/features/variables/adhoc/urlParser.test.ts:2987452506": [
[65, 16, 141, "Do not use any type assertions.", "2769250046"],
[65, 16, 118, "Do not use any type assertions.", "510137579"],
[83, 16, 130, "Do not use any type assertions.", "1366946792"],
[83, 16, 107, "Do not use any type assertions.", "2936397373"],
[101, 16, 131, "Do not use any type assertions.", "144318462"],
[101, 16, 108, "Do not use any type assertions.", "3807309291"]
],
"public/app/features/variables/adhoc/urlParser.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/variables/constant/reducer.test.ts:3405783846": [
[25, 16, 234, "Do not use any type assertions.", "2319981266"],
[50, 16, 248, "Do not use any type assertions.", "1014063058"]
],
"public/app/features/variables/constant/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/variables/custom/reducer.test.ts:134441915": [
[26, 16, 591, "Do not use any type assertions.", "3370154250"],
[66, 16, 595, "Do not use any type assertions.", "269111563"],
[106, 16, 591, "Do not use any type assertions.", "3370154250"],
[146, 16, 591, "Do not use any type assertions.", "3370154250"],
[186, 16, 675, "Do not use any type assertions.", "4190996907"],
[226, 16, 643, "Do not use any type assertions.", "1621992171"],
[266, 16, 741, "Do not use any type assertions.", "4040164424"]
],
"public/app/features/variables/custom/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/variables/datasource/actions.test.ts:1988531225": [
[73, 25, 30, "Do not use any type assertions.", "3368833770"],
[73, 25, 20, "Do not use any type assertions.", "3781735909"]
],
"public/app/features/variables/datasource/actions.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/variables/datasource/reducer.test.ts:3810268406": [
[42, 19, 122, "Do not use any type assertions.", "1128427296"],
[42, 19, 95, "Do not use any type assertions.", "1445464854"],
[68, 17, 289, "Do not use any type assertions.", "1163370834"],
[68, 17, 262, "Do not use any type assertions.", "1371708324"],
[96, 17, 164, "Do not use any type assertions.", "2083564038"],
[96, 17, 137, "Do not use any type assertions.", "1045964400"],
[121, 17, 190, "Do not use any type assertions.", "862727142"],
[121, 17, 163, "Do not use any type assertions.", "2642551696"],
[146, 17, 289, "Do not use any type assertions.", "1163370834"],
[146, 17, 262, "Do not use any type assertions.", "1371708324"]
],
"public/app/features/variables/datasource/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -6545,10 +6317,6 @@ exports[`better eslint`] = {
"public/app/features/variables/editor/reducer.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/variables/editor/selectors.test.ts:3899398841": [
[31, 14, 30, "Do not use any type assertions.", "2442266942"],
[31, 14, 13, "Do not use any type assertions.", "2146830713"]
],
"public/app/features/variables/editor/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -6636,24 +6404,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "13"],
[0, 0, 0, "Do not use any type assertions.", "14"]
],
"public/app/features/variables/interval/actions.test.ts:4248380429": [
[61, 26, 264, "Do not use any type assertions.", "131381399"],
[61, 26, 253, "Do not use any type assertions.", "3294972071"],
[153, 19, 294, "Do not use any type assertions.", "2131058214"],
[153, 19, 283, "Do not use any type assertions.", "1881118838"],
[164, 23, 82, "Do not use any type assertions.", "1627890605"],
[164, 23, 67, "Do not use any type assertions.", "1552916760"],
[205, 19, 77, "Do not use any type assertions.", "4249574421"],
[205, 19, 66, "Do not use any type assertions.", "3164490597"],
[209, 23, 95, "Do not use any type assertions.", "3057227568"],
[209, 23, 80, "Do not use any type assertions.", "3466408677"]
],
"public/app/features/variables/interval/reducer.test.ts:1904364691": [
[26, 17, 452, "Do not use any type assertions.", "1039353885"],
[54, 17, 531, "Do not use any type assertions.", "90477989"],
[83, 17, 383, "Do not use any type assertions.", "2247774352"],
[109, 17, 383, "Do not use any type assertions.", "2360119824"]
],
"public/app/features/variables/interval/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -6750,34 +6500,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/variables/query/reducer.test.ts:2683949100": [
[33, 15, 297, "Do not use any type assertions.", "870412809"],
[33, 15, 275, "Do not use any type assertions.", "2289094168"],
[57, 15, 232, "Do not use any type assertions.", "856245141"],
[57, 15, 210, "Do not use any type assertions.", "730423940"],
[71, 32, 23, "Do not use any type assertions.", "3708401277"],
[79, 15, 152, "Do not use any type assertions.", "3814787877"],
[79, 15, 130, "Do not use any type assertions.", "847409396"],
[90, 32, 23, "Do not use any type assertions.", "3708401277"],
[98, 15, 161, "Do not use any type assertions.", "2826271963"],
[98, 15, 139, "Do not use any type assertions.", "3023155146"],
[119, 15, 239, "Do not use any type assertions.", "3216676945"],
[119, 15, 217, "Do not use any type assertions.", "218790208"],
[143, 15, 145, "Do not use any type assertions.", "2045537569"],
[143, 15, 123, "Do not use any type assertions.", "1230177264"],
[164, 15, 154, "Do not use any type assertions.", "2729983415"],
[164, 15, 132, "Do not use any type assertions.", "3717778278"],
[183, 15, 154, "Do not use any type assertions.", "2729983415"],
[183, 15, 132, "Do not use any type assertions.", "3717778278"],
[202, 15, 155, "Do not use any type assertions.", "1202875329"],
[202, 15, 133, "Do not use any type assertions.", "2833874128"],
[221, 15, 153, "Do not use any type assertions.", "3540111265"],
[221, 15, 131, "Do not use any type assertions.", "1593542256"],
[240, 15, 157, "Do not use any type assertions.", "1514620833"],
[240, 15, 135, "Do not use any type assertions.", "630652528"],
[259, 15, 161, "Do not use any type assertions.", "2826271963"],
[259, 15, 139, "Do not use any type assertions.", "3023155146"]
],
"public/app/features/variables/query/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -6845,20 +6567,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/variables/state/migrateVariablesDatasourceNameToRef.test.ts:1577481970": [
[33, 25, 35, "Do not use any type assertions.", "1540321028"],
[33, 25, 18, "Do not use any type assertions.", "2747901642"],
[69, 25, 35, "Do not use any type assertions.", "1540321028"],
[69, 25, 18, "Do not use any type assertions.", "2747901642"]
],
"public/app/features/variables/state/onTimeRangeUpdated.test.ts:1138086757": [
[60, 26, 66, "Do not use any type assertions.", "2505932284"],
[60, 26, 51, "Do not use any type assertions.", "1748196521"],
[66, 25, 65, "Do not use any type assertions.", "1670117745"],
[66, 25, 47, "Do not use any type assertions.", "3235618000"],
[76, 25, 114, "Do not use any type assertions.", "1953052055"],
[76, 25, 95, "Do not use any type assertions.", "4074295433"]
],
"public/app/features/variables/state/processVariable.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@@ -6883,10 +6591,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/features/variables/state/templateVarsChangedInUrl.test.ts:1110987658": [
[106, 25, 30, "Do not use any type assertions.", "2475764786"],
[106, 25, 16, "Do not use any type assertions.", "4025864488"]
],
"public/app/features/variables/state/transactionReducer.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -6914,10 +6618,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"]
],
"public/app/features/variables/textbox/reducer.test.ts:261547066": [
[25, 16, 357, "Do not use any type assertions.", "587262851"],
[55, 16, 385, "Do not use any type assertions.", "1609241603"]
],
"public/app/features/variables/textbox/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7117,16 +6817,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.test.ts:2861609538": [
[23, 6, 42, "Do not use any type assertions.", "3363057790"]
],
"public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.test.ts:3421494994": [
[27, 4, 42, "Do not use any type assertions.", "3363057790"]
],
"public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.test.tsx:3945737102": [
[55, 47, 66, "Do not use any type assertions.", "257719288"],
[62, 5, 40, "Do not use any type assertions.", "589617352"]
],
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7222,10 +6912,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "27"],
[0, 0, 0, "Unexpected any. Specify a different type.", "28"]
],
"public/app/plugins/datasource/cloudwatch/dynamic-labels/CompletionItemProvider.test.ts:2308040365": [
[13, 17, 20, "Do not use any type assertions.", "3987315101"],
[16, 4, 49, "Do not use any type assertions.", "657683743"]
],
"public/app/plugins/datasource/cloudwatch/guards.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7251,22 +6937,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.test.ts:28138160": [
[18, 6, 42, "Do not use any type assertions.", "3363057790"]
],
"public/app/plugins/datasource/cloudwatch/migrations/dashboardMigrations.test.ts:3779106092": [
[22, 56, 40, "Do not use any type assertions.", "3305965890"],
[23, 29, 38, "Do not use any type assertions.", "2308925956"],
[47, 27, 82, "Do not use any type assertions.", "4227293635"],
[57, 56, 40, "Do not use any type assertions.", "3305965890"]
],
"public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.test.ts:2059201503": [
[20, 8, 42, "Do not use any type assertions.", "3363057790"],
[34, 8, 42, "Do not use any type assertions.", "3363057790"],
[54, 8, 42, "Do not use any type assertions.", "3363057790"],
[67, 8, 42, "Do not use any type assertions.", "3363057790"],
[80, 8, 42, "Do not use any type assertions.", "3363057790"]
],
"public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -7307,20 +6977,11 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx:4070687403": [
[14, 6, 58, "Do not use any type assertions.", "2751778796"],
[14, 6, 48, "Do not use any type assertions.", "1905604299"]
],
"public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/plugins/datasource/dashboard/runSharedRequest.test.ts:2672788153": [
[9, 34, 28, "Do not use any type assertions.", "152590796"],
[9, 34, 20, "Do not use any type assertions.", "3781735909"],
[12, 15, 80, "Do not use any type assertions.", "930836956"]
],
"public/app/plugins/datasource/dashboard/runSharedRequest.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
@@ -7350,18 +7011,9 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx:1034090678": [
[20, 23, 47, "Do not use any type assertions.", "1006213347"],
[57, 22, 23, "Do not use any type assertions.", "1688867449"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx:883637991": [
[32, 20, 34, "Do not use any type assertions.", "537625310"],
[68, 20, 34, "Do not use any type assertions.", "537625310"],
[101, 22, 52, "Do not use any type assertions.", "2399718003"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7369,11 +7021,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.test.tsx:1095480782": [
[36, 22, 23, "Do not use any type assertions.", "1688867449"],
[71, 22, 23, "Do not use any type assertions.", "1688867449"],
[109, 22, 23, "Do not use any type assertions.", "1688867449"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7385,15 +7032,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.test.tsx:3374077294": [
[9, 23, 47, "Do not use any type assertions.", "4096689189"],
[34, 23, 50, "Do not use any type assertions.", "3587418721"]
],
"public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx:2538768775": [
[24, 18, 50, "Do not use any type assertions.", "1393827441"],
[65, 18, 50, "Do not use any type assertions.", "1393827441"],
[106, 18, 50, "Do not use any type assertions.", "1393827441"]
],
"public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -7499,9 +7137,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "46"],
[0, 0, 0, "Unexpected any. Specify a different type.", "47"]
],
"public/app/plugins/datasource/elasticsearch/hooks/useFields.test.tsx:2288057911": [
[31, 20, 34, "Do not use any type assertions.", "537625310"]
],
"public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -7673,10 +7308,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx:804735513": [
[108, 15, 275, "Do not use any type assertions.", "3095409356"],
[128, 15, 273, "Do not use any type assertions.", "2697731533"]
],
"public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -7706,47 +7337,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts:1331364170": [
[10, 6, 59, "Do not use any type assertions.", "3685154675"],
[10, 6, 49, "Do not use any type assertions.", "1184085652"],
[26, 26, 354, "Do not use any type assertions.", "1354393999"],
[28, 10, 264, "Do not use any type assertions.", "297413427"],
[55, 26, 356, "Do not use any type assertions.", "2571179215"],
[57, 10, 266, "Do not use any type assertions.", "2917322995"],
[81, 26, 359, "Do not use any type assertions.", "2300363979"],
[83, 10, 269, "Do not use any type assertions.", "3832005239"],
[110, 26, 368, "Do not use any type assertions.", "752258440"],
[112, 10, 278, "Do not use any type assertions.", "3555784980"],
[136, 26, 384, "Do not use any type assertions.", "2278570570"],
[138, 10, 294, "Do not use any type assertions.", "3016568982"],
[165, 26, 385, "Do not use any type assertions.", "2272659527"],
[167, 10, 295, "Do not use any type assertions.", "3629245051"],
[191, 26, 401, "Do not use any type assertions.", "1343203141"],
[193, 10, 311, "Do not use any type assertions.", "128920633"],
[222, 26, 403, "Do not use any type assertions.", "1142769670"],
[224, 10, 313, "Do not use any type assertions.", "1484700762"],
[250, 26, 419, "Do not use any type assertions.", "2535472964"],
[252, 10, 329, "Do not use any type assertions.", "3679831256"],
[281, 26, 412, "Do not use any type assertions.", "2392166925"],
[283, 10, 322, "Do not use any type assertions.", "3950546289"],
[309, 26, 426, "Do not use any type assertions.", "3130099458"],
[311, 10, 336, "Do not use any type assertions.", "2465267934"],
[338, 26, 348, "Do not use any type assertions.", "553271343"],
[340, 10, 258, "Do not use any type assertions.", "1814519763"],
[365, 26, 362, "Do not use any type assertions.", "2434888097"],
[367, 10, 272, "Do not use any type assertions.", "1101004957"],
[399, 26, 144, "Do not use any type assertions.", "3556681124"],
[400, 18, 75, "Do not use any type assertions.", "1992896756"],
[400, 18, 54, "Do not use any type assertions.", "2666540601"],
[410, 26, 281, "Do not use any type assertions.", "3539142992"],
[412, 10, 191, "Do not use any type assertions.", "762876748"],
[438, 26, 412, "Do not use any type assertions.", "2392166925"],
[440, 10, 322, "Do not use any type assertions.", "3950546289"],
[470, 24, 245, "Do not use any type assertions.", "2341848736"],
[472, 8, 163, "Do not use any type assertions.", "1154794300"],
[497, 24, 334, "Do not use any type assertions.", "994281039"],
[499, 8, 252, "Do not use any type assertions.", "207432947"]
],
"public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -7961,10 +7551,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"]
],
"public/app/plugins/datasource/graphite/specs/gfunc.test.ts:2185945634": [
[90, 23, 30, "Do not use any type assertions.", "2243881570"],
[90, 23, 20, "Do not use any type assertions.", "3781735909"]
],
"public/app/plugins/datasource/graphite/specs/graphite_query.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -8007,18 +7593,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/influxdb/components/InfluxCheatSheet.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx:2172472189": [
[36, 3, 55, "Do not use any type assertions.", "601103896"],
[90, 41, 88, "Do not use any type assertions.", "1575686587"],
[90, 41, 68, "Do not use any type assertions.", "1096390308"],
[104, 12, 55, "Do not use any type assertions.", "601103896"],
[111, 12, 36, "Do not use any type assertions.", "3525546751"],
[118, 12, 49, "Do not use any type assertions.", "2352161943"]
],
"public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.test.tsx:1091402403": [
[40, 39, 84, "Do not use any type assertions.", "2017206331"],
[40, 39, 64, "Do not use any type assertions.", "3281675556"]
],
"public/app/plugins/datasource/influxdb/datasource.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -52,7 +52,6 @@ export interface FeatureToggles {
savedItems?: boolean;
cloudWatchDynamicLabels?: boolean;
datasourceQueryMultiStatus?: boolean;
azureMonitorExperimentalUI?: boolean;
traceToMetrics?: boolean;
prometheusStreamingJSONParser?: boolean;
validateDashboardsOnSave?: boolean;
-6
View File
@@ -204,12 +204,6 @@ var (
Description: "Introduce HTTP 207 Multi Status for api/ds/query",
State: FeatureStateAlpha,
},
{
Name: "azureMonitorExperimentalUI",
Description: "Use grafana-experimental UI in Azure Monitor",
State: FeatureStateAlpha,
FrontendOnly: true,
},
{
Name: "traceToMetrics",
Description: "Enable trace to metrics links",
-4
View File
@@ -151,10 +151,6 @@ const (
// Introduce HTTP 207 Multi Status for api/ds/query
FlagDatasourceQueryMultiStatus = "datasourceQueryMultiStatus"
// FlagAzureMonitorExperimentalUI
// Use grafana-experimental UI in Azure Monitor
FlagAzureMonitorExperimentalUI = "azureMonitorExperimentalUI"
// FlagTraceToMetrics
// Enable trace to metrics links
FlagTraceToMetrics = "traceToMetrics"
@@ -1,8 +1,6 @@
import React, { useEffect, useState, useRef } from 'react';
import { EditorRows, EditorRow, EditorFieldGroup } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { InlineFieldRow } from '@grafana/ui';
import Datasource from '../../datasource';
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types';
@@ -54,62 +52,34 @@ const ArgQueryEditor: React.FC<ArgQueryEditorProps> = ({
.catch((err) => setError(ERROR_SOURCE, err));
}, [datasource, onChange, query, setError]);
if (config.featureToggles.azureMonitorExperimentalUI) {
return (
<span data-testid="azure-monitor-arg-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<SubscriptionField
multiSelect
subscriptions={subscriptions}
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</EditorFieldGroup>
</EditorRow>
</EditorRows>
<QueryField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</span>
);
} else {
return (
<div data-testid="azure-monitor-arg-query-editor">
<InlineFieldRow>
<SubscriptionField
multiSelect
subscriptions={subscriptions}
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</InlineFieldRow>
<QueryField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</div>
);
}
return (
<span data-testid="azure-monitor-arg-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<SubscriptionField
multiSelect
subscriptions={subscriptions}
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</EditorFieldGroup>
</EditorRow>
</EditorRows>
<QueryField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</span>
);
};
export default ArgQueryEditor;
@@ -1,7 +1,6 @@
import React from 'react';
import { EditorField } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { InlineField } from '@grafana/ui';
import { Props as InlineFieldProps } from '@grafana/ui/src/components/Forms/InlineField';
@@ -16,7 +15,7 @@ const DEFAULT_LABEL_WIDTH = 18;
export const Field = (props: Props) => {
const { labelWidth, inlineField, ...remainingProps } = props;
if (config.featureToggles.azureMonitorExperimentalUI && !inlineField) {
if (!inlineField) {
return <EditorField width={labelWidth || DEFAULT_LABEL_WIDTH} {...remainingProps} />;
} else {
return <InlineField labelWidth={labelWidth || DEFAULT_LABEL_WIDTH} {...remainingProps} />;
@@ -1,7 +1,6 @@
import React from 'react';
import { EditorRows, EditorRow, EditorFieldGroup } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Alert } from '@grafana/ui';
import Datasource from '../../datasource';
@@ -35,81 +34,32 @@ const LogsQueryEditor: React.FC<LogsQueryEditorProps> = ({
}) => {
const migrationError = useMigrations(datasource, query, onChange);
if (config.featureToggles.azureMonitorExperimentalUI) {
return (
<span data-testid="azure-monitor-logs-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<ResourceField
query={query}
datasource={datasource}
inlineField={true}
labelWidth={10}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[
ResourceRowType.Subscription,
ResourceRowType.ResourceGroup,
ResourceRowType.Resource,
ResourceRowType.Variable,
]}
setResource={setResource}
resourceUri={query.azureLogAnalytics?.resource}
queryType="logs"
/>
</EditorFieldGroup>
</EditorRow>
<QueryField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<EditorRow>
<EditorFieldGroup>
{!hideFormatAs && (
<FormatAsField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
)}
{migrationError && <Alert title={migrationError.title}>{migrationError.message}</Alert>}
</EditorFieldGroup>
</EditorRow>
</EditorRows>
</span>
);
} else {
return (
<div data-testid="azure-monitor-logs-query-editor">
<ResourceField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[
ResourceRowType.Subscription,
ResourceRowType.ResourceGroup,
ResourceRowType.Resource,
ResourceRowType.Variable,
]}
setResource={setResource}
resourceUri={query.azureLogAnalytics?.resource}
queryType="logs"
/>
return (
<span data-testid="azure-monitor-logs-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<ResourceField
query={query}
datasource={datasource}
inlineField={true}
labelWidth={10}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[
ResourceRowType.Subscription,
ResourceRowType.ResourceGroup,
ResourceRowType.Resource,
ResourceRowType.Variable,
]}
setResource={setResource}
resourceUri={query.azureLogAnalytics?.resource}
queryType="logs"
/>
</EditorFieldGroup>
</EditorRow>
<QueryField
query={query}
datasource={datasource}
@@ -118,22 +68,25 @@ const LogsQueryEditor: React.FC<LogsQueryEditorProps> = ({
onQueryChange={onChange}
setError={setError}
/>
<EditorRow>
<EditorFieldGroup>
{!hideFormatAs && (
<FormatAsField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
)}
{!hideFormatAs && (
<FormatAsField
query={query}
datasource={datasource}
subscriptionId={subscriptionId}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
)}
{migrationError && <Alert title={migrationError.title}>{migrationError.message}</Alert>}
</div>
);
}
{migrationError && <Alert title={migrationError.title}>{migrationError.message}</Alert>}
</EditorFieldGroup>
</EditorRow>
</EditorRows>
</span>
);
};
export default LogsQueryEditor;
@@ -44,7 +44,6 @@ const AggregationField: React.FC<AggregationFieldProps> = ({
value={query.azureMonitor?.aggregation}
onChange={handleChange}
options={options}
width={38}
isLoading={isLoading}
/>
</Field>
@@ -9,7 +9,6 @@ import createMockPanelData from '../../__mocks__/panelData';
import createMockQuery from '../../__mocks__/query';
import DimensionFields from './DimensionFields';
import NewDimensionFields from './NewDimensionFields';
import { appendDimensionFilter, setDimensionFilterValue } from './setQueryValue';
const variableOptionGroup = {
@@ -18,365 +17,346 @@ const variableOptionGroup = {
};
const user = userEvent.setup();
const tests = [
{
component: DimensionFields,
label: 'Dimension Fields',
addDimension: async () => {
const addDimension = await screen.findByText('Add new dimension');
await user.click(addDimension);
},
},
{
component: NewDimensionFields,
label: 'Dimension Fields experimental UI',
addDimension: async () => {
const addDimension = await screen.findByLabelText('Add');
await user.click(addDimension);
},
},
];
describe(`Azure Monitor QueryEditor`, () => {
const mockDatasource = createMockDatasource();
for (const t of tests) {
describe(`Azure Monitor QueryEditor: ${t.label}`, () => {
const mockDatasource = createMockDatasource();
it('should render a dimension filter', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
const onQueryChange = jest.fn();
const dimensionOptions = [
{ label: 'Test Dimension 1', value: 'TestDimension1' },
{ label: 'Test Dimension 2', value: 'TestDimension2' },
];
const { rerender } = render(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
it('should render a dimension filter', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
const onQueryChange = jest.fn();
const dimensionOptions = [
{ label: 'Test Dimension 1', value: 'TestDimension1' },
{ label: 'Test Dimension 2', value: 'TestDimension2' },
];
const { rerender } = render(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const addDimension = await screen.findByLabelText('Add');
await user.click(addDimension);
await t.addDimension();
mockQuery = appendDimensionFilter(mockQuery);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: '', operator: 'eq', filters: [] }],
},
});
rerender(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const dimensionSelect = await screen.findByText('Field');
await selectOptionInTest(dimensionSelect, 'Test Dimension 1');
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
},
});
expect(screen.queryByText('Test Dimension 1')).toBeInTheDocument();
expect(screen.queryByText('==')).toBeInTheDocument();
mockQuery = appendDimensionFilter(mockQuery);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: '', operator: 'eq', filters: [] }],
},
});
it('correctly filters out dimensions when selected', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
rerender(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const dimensionSelect = await screen.findByText('Field');
await selectOptionInTest(dimensionSelect, 'Test Dimension 1');
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
};
const onQueryChange = jest.fn();
const dimensionOptions = [
{ label: 'Test Dimension 1', value: 'TestDimension1' },
{ label: 'Test Dimension 2', value: 'TestDimension2' },
];
const { rerender } = render(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
await t.addDimension();
mockQuery = appendDimensionFilter(mockQuery);
rerender(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const dimensionSelect = await screen.findByText('Field');
await user.click(dimensionSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(1);
expect(options[0]).toHaveTextContent('Test Dimension 2');
},
});
expect(screen.queryByText('Test Dimension 1')).toBeInTheDocument();
expect(screen.queryByText('==')).toBeInTheDocument();
});
it('correctly displays dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
it('correctly filters out dimensions when selected', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
};
const onQueryChange = jest.fn();
const dimensionOptions = [
{ label: 'Test Dimension 1', value: 'TestDimension1' },
{ label: 'Test Dimension 2', value: 'TestDimension2' },
];
const { rerender } = render(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const addDimension = await screen.findByLabelText('Add');
await user.click(addDimension);
mockQuery = appendDimensionFilter(mockQuery);
rerender(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const dimensionSelect = await screen.findByText('Field');
await user.click(dimensionSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(1);
expect(options[0]).toHaveTextContent('Test Dimension 2');
});
it('correctly displays dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
};
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
render(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = await screen.findByText('Select value(s)');
await user.click(labelSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(1);
expect(options[0]).toHaveTextContent('testlabel');
});
it('correctly updates dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: ['testlabel'] }],
};
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
const { rerender } = render(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
await screen.findByText('testlabel');
const labelClear = await screen.findByLabelText('Remove testlabel');
await user.click(labelClear);
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', []);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
};
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
render(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = await screen.findByText('Select value(s)');
await user.click(labelSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(1);
expect(options[0]).toHaveTextContent('testlabel');
},
});
mockPanelData.series = [
...mockPanelData.series,
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
rerender(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = screen.getByLabelText('dimension-labels-select');
await openMenu(labelSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(2);
expect(options[0]).toHaveTextContent('testlabel');
expect(options[1]).toHaveTextContent('testlabel2');
});
it('correctly updates dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockQuery.azureMonitor = {
it('correctly selects multiple dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
mockQuery = appendDimensionFilter(mockQuery, 'TestDimension1');
const { rerender } = render(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = screen.getByLabelText('dimension-labels-select');
await user.click(labelSelect);
await openMenu(labelSelect);
screen.getByText('testlabel');
screen.getByText('testlabel2');
await selectOptionInTest(labelSelect, 'testlabel');
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', ['testlabel']);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: ['testlabel'] }],
};
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
const { rerender } = render(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
await screen.findByText('testlabel');
const labelClear = await screen.findByLabelText('Remove testlabel');
await user.click(labelClear);
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', []);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: [] }],
},
});
mockPanelData.series = [
...mockPanelData.series,
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
rerender(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = screen.getByLabelText('dimension-labels-select');
await openMenu(labelSelect);
const options = await screen.findAllByLabelText('Select option');
expect(options).toHaveLength(2);
expect(options[0]).toHaveTextContent('testlabel');
expect(options[1]).toHaveTextContent('testlabel2');
},
});
it('correctly selects multiple dimension labels', async () => {
let mockQuery = createMockQuery();
const mockPanelData = createMockPanelData();
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
const onQueryChange = jest.fn();
const dimensionOptions = [{ label: 'Test Dimension 1', value: 'TestDimension1' }];
mockQuery = appendDimensionFilter(mockQuery, 'TestDimension1');
const { rerender } = render(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect = screen.getByLabelText('dimension-labels-select');
await user.click(labelSelect);
await openMenu(labelSelect);
screen.getByText('testlabel');
screen.getByText('testlabel2');
await selectOptionInTest(labelSelect, 'testlabel');
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', ['testlabel']);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: ['testlabel'] }],
},
});
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
rerender(
<t.component
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect2 = screen.getByLabelText('dimension-labels-select');
await openMenu(labelSelect2);
const refreshedOptions = await screen.findAllByLabelText('Select options menu');
expect(refreshedOptions).toHaveLength(1);
expect(refreshedOptions[0]).toHaveTextContent('testlabel2');
await selectOptionInTest(labelSelect2, 'testlabel2');
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', ['testlabel', 'testlabel2']);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: ['testlabel', 'testlabel2'] }],
},
});
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
];
rerender(
<DimensionFields
data={mockPanelData}
subscriptionId="123"
query={mockQuery}
onQueryChange={onQueryChange}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
setError={() => {}}
dimensionOptions={dimensionOptions}
/>
);
const labelSelect2 = screen.getByLabelText('dimension-labels-select');
await openMenu(labelSelect2);
const refreshedOptions = await screen.findAllByLabelText('Select options menu');
expect(refreshedOptions).toHaveLength(1);
expect(refreshedOptions[0]).toHaveTextContent('testlabel2');
await selectOptionInTest(labelSelect2, 'testlabel2');
mockQuery = setDimensionFilterValue(mockQuery, 0, 'filters', ['testlabel', 'testlabel2']);
expect(onQueryChange).toHaveBeenCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
dimensionFilters: [{ dimension: 'TestDimension1', operator: 'eq', filters: ['testlabel', 'testlabel2'] }],
},
});
mockPanelData.series = [
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel' },
},
],
},
{
...mockPanelData.series[0],
fields: [
{
...mockPanelData.series[0].fields[0],
name: 'Test Dimension 1',
labels: { testdimension1: 'testlabel2' },
},
],
},
];
});
}
});
@@ -1,12 +1,13 @@
import React, { useEffect, useMemo, useState } from 'react';
import { SelectableValue, DataFrame, PanelData } from '@grafana/data';
import { Button, Select, HorizontalGroup, VerticalGroup, MultiSelect } from '@grafana/ui';
import { SelectableValue, DataFrame, PanelData, Labels } from '@grafana/data';
import { AccessoryButton, EditorList } from '@grafana/experimental';
import { Select, HorizontalGroup, MultiSelect } from '@grafana/ui';
import { AzureMetricDimension, AzureMonitorOption, AzureMonitorQuery, AzureQueryEditorFieldProps } from '../../types';
import { Field } from '../Field';
import { appendDimensionFilter, removeDimensionFilter, setDimensionFilterValue } from './setQueryValue';
import { setDimensionFilters } from './setQueryValue';
interface DimensionFieldsProps extends AzureQueryEditorFieldProps {
dimensionOptions: AzureMonitorOption[];
@@ -28,16 +29,14 @@ const useDimensionLabels = (data: PanelData | undefined, query: AzureMonitorQuer
const labels = fields
.map((fields) => fields.labels)
.flat()
.filter((item) => item!);
.filter((item): item is Labels => item !== null && item !== undefined);
for (const label of labels) {
// Labels only exist for series that have a dimension selected
if (label) {
for (const [dimension, value] of Object.entries(label)) {
if (labelsObj[dimension]) {
labelsObj[dimension].add(value);
} else {
labelsObj[dimension] = new Set([value]);
}
for (const [dimension, value] of Object.entries(label)) {
if (labelsObj[dimension]) {
labelsObj[dimension].add(value);
} else {
labelsObj[dimension] = new Set([value]);
}
}
}
@@ -87,24 +86,14 @@ const DimensionFields: React.FC<DimensionFieldsProps> = ({ data, query, dimensio
return t;
}, [dimensionFilters, dimensionOptions]);
const addFilter = () => {
onQueryChange(appendDimensionFilter(query));
};
const removeFilter = (index: number) => {
onQueryChange(removeDimensionFilter(query, index));
};
const onFieldChange = <Key extends keyof AzureMetricDimension>(
filterIndex: number,
fieldName: Key,
value: AzureMetricDimension[Key]
item: Partial<AzureMetricDimension>,
value: AzureMetricDimension[Key],
onChange: (item: Partial<AzureMetricDimension>) => void
) => {
onQueryChange(setDimensionFilterValue(query, filterIndex, fieldName, value));
};
const onFilterInputChange = (index: number, v: SelectableValue<string> | null) => {
onFieldChange(index, 'filters', [v?.value ?? '']);
item[fieldName] = value;
onChange(item);
};
const getValidDimensionOptions = (selectedDimension: string) => {
@@ -133,7 +122,6 @@ const DimensionFields: React.FC<DimensionFieldsProps> = ({ data, query, dimensio
}
return labelOptions;
};
const getValidOperators = (selectedOperator: string) => {
if (dimensionOperators.find((operator: SelectableValue) => operator.value === selectedOperator)) {
return dimensionOperators;
@@ -141,70 +129,76 @@ const DimensionFields: React.FC<DimensionFieldsProps> = ({ data, query, dimensio
return [...dimensionOperators, ...(selectedOperator ? [{ label: selectedOperator, value: selectedOperator }] : [])];
};
const onMultiSelectFilterChange = (index: number, v: Array<SelectableValue<string>>) => {
onFieldChange(
index,
'filters',
v.map((item) => item.value || '')
const changedFunc = (changed: Array<Partial<AzureMetricDimension>>) => {
const properData: AzureMetricDimension[] = changed.map((x) => {
return {
dimension: x.dimension ?? '',
operator: x.operator ?? 'eq',
filters: x.filters ?? [],
};
});
onQueryChange(setDimensionFilters(query, properData));
};
const renderFilters = (
item: Partial<AzureMetricDimension>,
onChange: (item: Partial<AzureMetricDimension>) => void,
onDelete: () => void
) => {
return (
<HorizontalGroup spacing="none">
<Select
menuShouldPortal
placeholder="Field"
value={item.dimension}
options={getValidDimensionOptions(item.dimension || '')}
onChange={(e) => onFieldChange('dimension', item, e.value ?? '', onChange)}
/>
<Select
menuShouldPortal
placeholder="Operation"
value={item.operator}
options={getValidOperators(item.operator || 'eq')}
onChange={(e) => onFieldChange('operator', item, e.value ?? '', onChange)}
allowCustomValue
/>
{item.operator === 'eq' || item.operator === 'ne' ? (
<MultiSelect
menuShouldPortal
placeholder="Select value(s)"
value={item.filters}
options={getValidMultiSelectOptions(item.filters, item.dimension ?? '')}
onChange={(e) =>
onFieldChange(
'filters',
item,
e.map((x) => x.value ?? ''),
onChange
)
}
aria-label={'dimension-labels-select'}
allowCustomValue
/>
) : (
// The API does not currently allow for multiple "starts with" clauses to be used.
<Select
menuShouldPortal
placeholder="Select value"
value={item.filters ? item.filters[0] : ''}
allowCustomValue
options={getValidFilterOptions(item.filters ? item.filters[0] : '', item.dimension ?? '')}
onChange={(e) => onFieldChange('filters', item, [e?.value ?? ''], onChange)}
isClearable
/>
)}
<AccessoryButton aria-label="Remove" icon="times" variant="secondary" onClick={onDelete} type="button" />
</HorizontalGroup>
);
};
return (
<Field label="Dimension">
<VerticalGroup spacing="xs">
{dimensionFilters.map((filter, index) => (
<HorizontalGroup key={index} spacing="xs">
<Select
placeholder="Field"
value={filter.dimension}
options={getValidDimensionOptions(filter.dimension)}
onChange={(v) => onFieldChange(index, 'dimension', v.value ?? '')}
width={38}
/>
<Select
menuShouldPortal
placeholder="Operation"
value={filter.operator}
options={getValidOperators(filter.operator)}
onChange={(v) => onFieldChange(index, 'operator', v.value ?? '')}
allowCustomValue
/>
{filter.operator === 'eq' || filter.operator === 'ne' ? (
<MultiSelect
menuShouldPortal
placeholder="Select value(s)"
value={filter.filters}
options={getValidMultiSelectOptions(filter.filters, filter.dimension)}
onChange={(v) => onMultiSelectFilterChange(index, v)}
aria-label={'dimension-labels-select'}
allowCustomValue
/>
) : (
// The API does not currently allow for multiple "starts with" clauses to be used.
<Select
menuShouldPortal
placeholder="Select value"
value={filter.filters ? filter.filters[0] : ''}
allowCustomValue
options={getValidFilterOptions(filter.filters ? filter.filters[0] : '', filter.dimension)}
onChange={(v) => onFilterInputChange(index, v)}
isClearable
/>
)}
<Button
variant="secondary"
size="md"
icon="trash-alt"
aria-label="Remove"
onClick={() => removeFilter(index)}
></Button>
</HorizontalGroup>
))}
<Button variant="secondary" size="md" onClick={addFilter}>
Add new dimension
</Button>
</VerticalGroup>
<Field label="Dimensions">
<EditorList items={dimensionFilters} onChange={changedFunc} renderItem={renderFilters} />
</Field>
);
};
@@ -34,7 +34,6 @@ const MetricNameField: React.FC<MetricNameProps> = ({ metricNames, query, variab
value={query.azureMonitor?.metricName ?? null}
onChange={handleChange}
options={options}
width={38}
allowCustomValue
/>
</Field>
@@ -46,7 +46,6 @@ const MetricNamespaceField: React.FC<MetricNamespaceFieldProps> = ({
value={query.azureMonitor?.metricNamespace}
onChange={handleChange}
options={options}
width={38}
allowCustomValue
/>
</Field>
@@ -3,8 +3,6 @@ import userEvent from '@testing-library/user-event';
import React from 'react';
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
import { config } from '@grafana/runtime';
import createMockDatasource from '../../__mocks__/datasource';
import { createMockInstanceSetttings } from '../../__mocks__/instanceSettings';
import createMockPanelData from '../../__mocks__/panelData';
@@ -23,15 +21,6 @@ const variableOptionGroup = {
options: [],
};
const tests = [
{
id: 'azure-monitor-metrics-query-editor-with-resource-picker',
},
{
id: 'azure-monitor-metrics-query-editor-with-experimental-ui',
},
];
export function createMockResourcePickerData() {
const mockDatasource = new ResourcePickerData(createMockInstanceSetttings());
@@ -46,215 +35,210 @@ export function createMockResourcePickerData() {
return mockDatasource;
}
for (const t of tests) {
describe(`MetricsQueryEditor: ${t.id}`, () => {
const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
const mockPanelData = createMockPanelData();
describe('MetricsQueryEditor', () => {
const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
const mockPanelData = createMockPanelData();
beforeEach(() => {
window.HTMLElement.prototype.scrollIntoView = function () {};
config.featureToggles.azureMonitorExperimentalUI =
t.id === 'azure-monitor-metrics-query-editor-with-experimental-ui';
});
afterEach(() => {
window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
config.featureToggles.azureMonitorExperimentalUI = false;
});
beforeEach(() => {
window.HTMLElement.prototype.scrollIntoView = function () {};
});
afterEach(() => {
window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
});
it('should render', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
it('should render', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={() => {}}
setError={() => {}}
/>
);
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={() => {}}
setError={() => {}}
/>
);
expect(await screen.findByTestId(t.id)).toBeInTheDocument();
});
expect(await screen.findByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument();
});
it('should change resource when a resource is selected in the ResourcePicker', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
delete query?.azureMonitor?.resourceUri;
const onChange = jest.fn();
it('should change resource when a resource is selected in the ResourcePicker', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
delete query?.azureMonitor?.resourceUri;
const onChange = jest.fn();
render(
<MetricsQueryEditor
data={mockPanelData}
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
render(
<MetricsQueryEditor
data={mockPanelData}
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
expect(resourcePickerButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Primary Subscription' })).not.toBeInTheDocument();
resourcePickerButton.click();
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
expect(resourcePickerButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Primary Subscription' })).not.toBeInTheDocument();
resourcePickerButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
expect(subscriptionButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand A Great Resource Group' })).not.toBeInTheDocument();
subscriptionButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
expect(subscriptionButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand A Great Resource Group' })).not.toBeInTheDocument();
subscriptionButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
expect(resourceGroupButton).toBeInTheDocument();
expect(screen.queryByLabelText('web-server')).not.toBeInTheDocument();
resourceGroupButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
expect(resourceGroupButton).toBeInTheDocument();
expect(screen.queryByLabelText('web-server')).not.toBeInTheDocument();
resourceGroupButton.click();
const checkbox = await screen.findByLabelText('web-server');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
const checkbox = await screen.findByLabelText('web-server');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
expect(onChange).toBeCalledTimes(1);
expect(onChange).toBeCalledWith(
expect.objectContaining({
azureMonitor: expect.objectContaining({
resourceUri:
'/subscriptions/def-456/resourceGroups/dev-3/providers/Microsoft.Compute/virtualMachines/web-server',
}),
})
);
});
expect(onChange).toBeCalledTimes(1);
expect(onChange).toBeCalledWith(
expect.objectContaining({
azureMonitor: expect.objectContaining({
resourceUri:
'/subscriptions/def-456/resourceGroups/dev-3/providers/Microsoft.Compute/virtualMachines/web-server',
}),
})
);
});
it('should reset metric namespace, metric name, and aggregation fields after selecting a new resource when a valid query has already been set', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
const onChange = jest.fn();
it('should reset metric namespace, metric name, and aggregation fields after selecting a new resource when a valid query has already been set', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
const onChange = jest.fn();
render(
<MetricsQueryEditor
data={mockPanelData}
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
render(
<MetricsQueryEditor
data={mockPanelData}
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const resourcePickerButton = await screen.findByRole('button', { name: /grafana/ });
const resourcePickerButton = await screen.findByRole('button', { name: /grafana/ });
expect(screen.getByText('Microsoft.Compute/virtualMachines')).toBeInTheDocument();
expect(screen.getByText('Metric A')).toBeInTheDocument();
expect(screen.getByText('Average')).toBeInTheDocument();
expect(screen.getByText('Microsoft.Compute/virtualMachines')).toBeInTheDocument();
expect(screen.getByText('Metric A')).toBeInTheDocument();
expect(screen.getByText('Average')).toBeInTheDocument();
expect(resourcePickerButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Primary Subscription' })).not.toBeInTheDocument();
resourcePickerButton.click();
expect(resourcePickerButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Primary Subscription' })).not.toBeInTheDocument();
resourcePickerButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Dev Subscription' });
expect(subscriptionButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Development 3' })).not.toBeInTheDocument();
subscriptionButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Dev Subscription' });
expect(subscriptionButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand Development 3' })).not.toBeInTheDocument();
subscriptionButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand Development 3' });
expect(resourceGroupButton).toBeInTheDocument();
expect(screen.queryByLabelText('db-server')).not.toBeInTheDocument();
resourceGroupButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand Development 3' });
expect(resourceGroupButton).toBeInTheDocument();
expect(screen.queryByLabelText('db-server')).not.toBeInTheDocument();
resourceGroupButton.click();
const checkbox = await screen.findByLabelText('db-server');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
const checkbox = await screen.findByLabelText('db-server');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
expect(onChange).toBeCalledTimes(1);
expect(onChange).toBeCalledWith(
expect.objectContaining({
azureMonitor: expect.objectContaining({
resourceUri:
'/subscriptions/def-456/resourceGroups/dev-3/providers/Microsoft.Compute/virtualMachines/db-server',
metricNamespace: undefined,
metricName: undefined,
aggregation: undefined,
timeGrain: '',
dimensionFilters: [],
}),
})
);
});
it('should change the metric name when selected', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const onChange = jest.fn();
const mockQuery = createMockQuery();
mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([
{
value: 'metric-a',
text: 'Metric A',
},
{
value: 'metric-b',
text: 'Metric B',
},
]);
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const metrics = await screen.findByLabelText('Metric');
expect(metrics).toBeInTheDocument();
await selectOptionInTest(metrics, 'Metric B');
expect(onChange).toHaveBeenLastCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
metricName: 'metric-b',
expect(onChange).toBeCalledTimes(1);
expect(onChange).toBeCalledWith(
expect.objectContaining({
azureMonitor: expect.objectContaining({
resourceUri:
'/subscriptions/def-456/resourceGroups/dev-3/providers/Microsoft.Compute/virtualMachines/db-server',
metricNamespace: undefined,
metricName: undefined,
aggregation: undefined,
timeGrain: '',
},
});
});
dimensionFilters: [],
}),
})
);
});
it('should change the aggregation type when selected', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const onChange = jest.fn();
const mockQuery = createMockQuery();
it('should change the metric name when selected', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const onChange = jest.fn();
const mockQuery = createMockQuery();
mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([
{
value: 'metric-a',
text: 'Metric A',
},
{
value: 'metric-b',
text: 'Metric B',
},
]);
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const aggregation = await screen.findByLabelText('Aggregation');
expect(aggregation).toBeInTheDocument();
await selectOptionInTest(aggregation, 'Maximum');
const metrics = await screen.findByLabelText('Metric');
expect(metrics).toBeInTheDocument();
await selectOptionInTest(metrics, 'Metric B');
expect(onChange).toHaveBeenLastCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
aggregation: 'Maximum',
},
});
expect(onChange).toHaveBeenLastCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
metricName: 'metric-b',
aggregation: undefined,
timeGrain: '',
},
});
});
}
it('should change the aggregation type when selected', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const onChange = jest.fn();
const mockQuery = createMockQuery();
render(
<MetricsQueryEditor
data={mockPanelData}
query={createMockQuery()}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const aggregation = await screen.findByLabelText('Aggregation');
expect(aggregation).toBeInTheDocument();
await selectOptionInTest(aggregation, 'Maximum');
expect(onChange).toHaveBeenLastCalledWith({
...mockQuery,
azureMonitor: {
...mockQuery.azureMonitor,
aggregation: 'Maximum',
},
});
});
});
@@ -1,10 +1,7 @@
import { css } from '@emotion/css';
import React from 'react';
import { PanelData } from '@grafana/data/src/types';
import { EditorRows, EditorRow, EditorFieldGroup } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { InlineFieldRow, useStyles2 } from '@grafana/ui';
import type Datasource from '../../datasource';
import type { AzureMonitorQuery, AzureMonitorOption, AzureMonitorErrorish } from '../../types';
@@ -16,7 +13,6 @@ import DimensionFields from './DimensionFields';
import LegendFormatField from './LegendFormatField';
import MetricNameField from './MetricNameField';
import MetricNamespaceField from './MetricNamespaceField';
import NewDimensionFields from './NewDimensionFields';
import TimeGrainField from './TimeGrainField';
import TopField from './TopField';
import { useMetricNames, useMetricNamespaces, useMetricMetadata } from './dataHooks';
@@ -39,187 +35,94 @@ const MetricsQueryEditor: React.FC<MetricsQueryEditorProps> = ({
onChange,
setError,
}) => {
const styles = useStyles2(getStyles);
const metricsMetadata = useMetricMetadata(query, datasource, onChange);
const metricNamespaces = useMetricNamespaces(query, datasource, onChange, setError);
const metricNames = useMetricNames(query, datasource, onChange, setError);
if (config.featureToggles.azureMonitorExperimentalUI) {
return (
<span data-testid="azure-monitor-metrics-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<ResourceField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[ResourceRowType.Resource]}
setResource={setResource}
resourceUri={query.azureMonitor?.resourceUri}
queryType={'metrics'}
/>
<MetricNamespaceField
metricNamespaces={metricNamespaces}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<MetricNameField
metricNames={metricNames}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</EditorFieldGroup>
</EditorRow>
<EditorRow>
<EditorFieldGroup>
<AggregationField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
aggregationOptions={metricsMetadata?.aggOptions ?? []}
isLoading={metricsMetadata.isLoading}
/>
<TimeGrainField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
timeGrainOptions={metricsMetadata?.timeGrains ?? []}
/>
</EditorFieldGroup>
</EditorRow>
<EditorRow>
<EditorFieldGroup>
<NewDimensionFields
data={data}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
dimensionOptions={metricsMetadata?.dimensions ?? []}
/>
</EditorFieldGroup>
</EditorRow>
<EditorRow>
<EditorFieldGroup>
<TopField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<LegendFormatField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</EditorFieldGroup>
</EditorRow>
</EditorRows>
</span>
);
} else {
return (
<div data-testid="azure-monitor-metrics-query-editor-with-resource-picker">
<InlineFieldRow className={styles.row}>
<ResourceField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[ResourceRowType.Resource]}
setResource={setResource}
resourceUri={query.azureMonitor?.resourceUri}
queryType="metrics"
/>
</InlineFieldRow>
<InlineFieldRow className={styles.row}>
<MetricNamespaceField
metricNamespaces={metricNamespaces}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<MetricNameField
metricNames={metricNames}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</InlineFieldRow>
<InlineFieldRow className={styles.row}>
<AggregationField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
aggregationOptions={metricsMetadata?.aggOptions ?? []}
isLoading={metricsMetadata.isLoading}
/>
<TimeGrainField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
timeGrainOptions={metricsMetadata?.timeGrains ?? []}
/>
</InlineFieldRow>
<DimensionFields
data={data}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
dimensionOptions={metricsMetadata?.dimensions ?? []}
/>
<TopField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<LegendFormatField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</div>
);
}
return (
<span data-testid="azure-monitor-metrics-query-editor-with-experimental-ui">
<EditorRows>
<EditorRow>
<EditorFieldGroup>
<ResourceField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
selectableEntryTypes={[ResourceRowType.Resource]}
setResource={setResource}
resourceUri={query.azureMonitor?.resourceUri}
queryType={'metrics'}
/>
<MetricNamespaceField
metricNamespaces={metricNamespaces}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<MetricNameField
metricNames={metricNames}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<AggregationField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
aggregationOptions={metricsMetadata?.aggOptions ?? []}
isLoading={metricsMetadata.isLoading}
/>
<TimeGrainField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
timeGrainOptions={metricsMetadata?.timeGrains ?? []}
/>
</EditorFieldGroup>
</EditorRow>
<EditorRow>
<EditorFieldGroup>
<DimensionFields
data={data}
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
dimensionOptions={metricsMetadata?.dimensions ?? []}
/>
</EditorFieldGroup>
</EditorRow>
<EditorRow>
<EditorFieldGroup>
<TopField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
<LegendFormatField
query={query}
datasource={datasource}
variableOptionGroup={variableOptionGroup}
onQueryChange={onChange}
setError={setError}
/>
</EditorFieldGroup>
</EditorRow>
</EditorRows>
</span>
);
};
const getStyles = () => ({
row: css({
rowGap: 0,
}),
});
export default MetricsQueryEditor;
@@ -1,206 +0,0 @@
import React, { useEffect, useMemo, useState } from 'react';
import { SelectableValue, DataFrame, PanelData, Labels } from '@grafana/data';
import { AccessoryButton, EditorList } from '@grafana/experimental';
import { Select, HorizontalGroup, MultiSelect } from '@grafana/ui';
import { AzureMetricDimension, AzureMonitorOption, AzureMonitorQuery, AzureQueryEditorFieldProps } from '../../types';
import { Field } from '../Field';
import { setDimensionFilters } from './setQueryValue';
interface DimensionFieldsProps extends AzureQueryEditorFieldProps {
dimensionOptions: AzureMonitorOption[];
}
interface DimensionLabels {
[key: string]: Set<string>;
}
const useDimensionLabels = (data: PanelData | undefined, query: AzureMonitorQuery) => {
const [dimensionLabels, setDimensionLabels] = useState<DimensionLabels>({});
useEffect(() => {
let labelsObj: DimensionLabels = {};
if (data?.series?.length) {
// Identify which series' in the dataframe are relevant to the current query
const series: DataFrame[] = data.series.flat().filter((series) => series.refId === query.refId);
const fields = series.flatMap((series) => series.fields);
// Retrieve labels for series fields
const labels = fields
.map((fields) => fields.labels)
.flat()
.filter((item): item is Labels => item !== null && item !== undefined);
for (const label of labels) {
// Labels only exist for series that have a dimension selected
for (const [dimension, value] of Object.entries(label)) {
if (labelsObj[dimension]) {
labelsObj[dimension].add(value);
} else {
labelsObj[dimension] = new Set([value]);
}
}
}
}
setDimensionLabels((prevLabels) => {
const newLabels: DimensionLabels = {};
const currentLabels = Object.keys(labelsObj);
if (currentLabels.length === 0) {
return prevLabels;
}
for (const label of currentLabels) {
if (prevLabels[label] && labelsObj[label].size < prevLabels[label].size) {
newLabels[label] = prevLabels[label];
} else {
newLabels[label] = labelsObj[label];
}
}
return newLabels;
});
}, [data?.series, query.refId]);
return dimensionLabels;
};
const NewDimensionFields: React.FC<DimensionFieldsProps> = ({ data, query, dimensionOptions, onQueryChange }) => {
const dimensionFilters = useMemo(
() => query.azureMonitor?.dimensionFilters ?? [],
[query.azureMonitor?.dimensionFilters]
);
const dimensionLabels = useDimensionLabels(data, query);
const dimensionOperators: Array<SelectableValue<string>> = [
{ label: '==', value: 'eq' },
{ label: '!=', value: 'ne' },
{ label: 'starts with', value: 'sw' },
];
const validDimensionOptions = useMemo(() => {
// We filter out any dimensions that have already been used in a filter as the API doesn't support having multiple filters with the same dimension name.
// The Azure portal also doesn't support this feature so it makes sense for consistency.
let t = dimensionOptions;
if (dimensionFilters.length) {
t = dimensionOptions.filter(
(val) => !dimensionFilters.some((dimensionFilter) => dimensionFilter.dimension === val.value)
);
}
return t;
}, [dimensionFilters, dimensionOptions]);
const onFieldChange = <Key extends keyof AzureMetricDimension>(
fieldName: Key,
item: Partial<AzureMetricDimension>,
value: AzureMetricDimension[Key],
onChange: (item: Partial<AzureMetricDimension>) => void
) => {
item[fieldName] = value;
onChange(item);
};
const getValidDimensionOptions = (selectedDimension: string) => {
return validDimensionOptions.concat(dimensionOptions.filter((item) => item.value === selectedDimension));
};
const getValidFilterOptions = (selectedFilter: string | undefined, dimension: string) => {
const dimensionFilters = Array.from(dimensionLabels[dimension.toLowerCase()] ?? []);
if (dimensionFilters.find((filter) => filter === selectedFilter)) {
return dimensionFilters.map((filter) => ({ value: filter, label: filter }));
}
return [...dimensionFilters, ...(selectedFilter && selectedFilter !== '*' ? [selectedFilter] : [])].map((item) => ({
value: item,
label: item,
}));
};
const getValidMultiSelectOptions = (selectedFilters: string[] | undefined, dimension: string) => {
const labelOptions = getValidFilterOptions(undefined, dimension);
if (selectedFilters) {
for (const filter of selectedFilters) {
if (!labelOptions.find((label) => label.value === filter)) {
labelOptions.push({ value: filter, label: filter });
}
}
}
return labelOptions;
};
const getValidOperators = (selectedOperator: string) => {
if (dimensionOperators.find((operator: SelectableValue) => operator.value === selectedOperator)) {
return dimensionOperators;
}
return [...dimensionOperators, ...(selectedOperator ? [{ label: selectedOperator, value: selectedOperator }] : [])];
};
const changedFunc = (changed: Array<Partial<AzureMetricDimension>>) => {
const properData: AzureMetricDimension[] = changed.map((x) => {
return {
dimension: x.dimension ?? '',
operator: x.operator ?? 'eq',
filters: x.filters ?? [],
};
});
onQueryChange(setDimensionFilters(query, properData));
};
const renderFilters = (
item: Partial<AzureMetricDimension>,
onChange: (item: Partial<AzureMetricDimension>) => void,
onDelete: () => void
) => {
return (
<HorizontalGroup spacing="none">
<Select
menuShouldPortal
placeholder="Field"
value={item.dimension}
options={getValidDimensionOptions(item.dimension || '')}
onChange={(e) => onFieldChange('dimension', item, e.value ?? '', onChange)}
/>
<Select
menuShouldPortal
placeholder="Operation"
value={item.operator}
options={getValidOperators(item.operator || 'eq')}
onChange={(e) => onFieldChange('operator', item, e.value ?? '', onChange)}
allowCustomValue
/>
{item.operator === 'eq' || item.operator === 'ne' ? (
<MultiSelect
menuShouldPortal
placeholder="Select value(s)"
value={item.filters}
options={getValidMultiSelectOptions(item.filters, item.dimension ?? '')}
onChange={(e) =>
onFieldChange(
'filters',
item,
e.map((x) => x.value ?? ''),
onChange
)
}
aria-label={'dimension-labels-select'}
allowCustomValue
/>
) : (
// The API does not currently allow for multiple "starts with" clauses to be used.
<Select
menuShouldPortal
placeholder="Select value"
value={item.filters ? item.filters[0] : ''}
allowCustomValue
options={getValidFilterOptions(item.filters ? item.filters[0] : '', item.dimension ?? '')}
onChange={(e) => onFieldChange('filters', item, [e?.value ?? ''], onChange)}
isClearable
/>
)}
<AccessoryButton aria-label="Remove" icon="times" variant="secondary" onClick={onDelete} type="button" />
</HorizontalGroup>
);
};
return (
<Field label="Dimensions">
<EditorList items={dimensionFilters} onChange={changedFunc} renderItem={renderFilters} />
</Field>
);
};
export default NewDimensionFields;
@@ -58,7 +58,6 @@ const TimeGrainField: React.FC<TimeGrainFieldProps> = ({
value={query.azureMonitor?.timeGrain}
onChange={handleChange}
options={timeGrains}
width={38}
/>
</Field>
);
@@ -2,7 +2,6 @@ import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
import { config } from '@grafana/runtime';
import * as ui from '@grafana/ui';
import createMockDatasource from '../../__mocks__/datasource';
@@ -30,7 +29,7 @@ describe('Azure Monitor QueryEditor', () => {
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
await waitFor(() =>
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-resource-picker')).toBeInTheDocument()
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument()
);
});
@@ -42,7 +41,9 @@ describe('Azure Monitor QueryEditor', () => {
};
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
await waitFor(() => expect(screen.queryByTestId('azure-monitor-logs-query-editor')).toBeInTheDocument());
await waitFor(() =>
expect(screen.queryByTestId('azure-monitor-logs-query-editor-with-experimental-ui')).toBeInTheDocument()
);
});
it('changes the query type when selected', async () => {
@@ -52,7 +53,7 @@ describe('Azure Monitor QueryEditor', () => {
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={onChange} onRunQuery={() => {}} />);
await waitFor(() => expect(screen.getByTestId('azure-monitor-query-editor')).toBeInTheDocument());
const metrics = await screen.findByLabelText('Service');
const metrics = await screen.findByLabelText(/Service/);
await selectOptionInTest(metrics, 'Logs');
expect(onChange).toHaveBeenCalledWith({
@@ -68,16 +69,12 @@ describe('Azure Monitor QueryEditor', () => {
<QueryEditor query={createMockQuery()} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />
);
await waitFor(() =>
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-resource-picker')).toBeInTheDocument()
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument()
);
expect(screen.getByText('An error occurred while requesting metadata from Azure Monitor')).toBeInTheDocument();
});
it('should render the experimental QueryHeader when feature toggle is enabled', async () => {
const originalConfigValue = config.featureToggles.azureMonitorExperimentalUI;
config.featureToggles.azureMonitorExperimentalUI = true;
const mockDatasource = createMockDatasource();
const mockQuery = {
...createMockQuery(),
@@ -87,19 +84,5 @@ describe('Azure Monitor QueryEditor', () => {
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
await waitFor(() => expect(screen.getByTestId('azure-monitor-experimental-header')).toBeInTheDocument());
config.featureToggles.azureMonitorExperimentalUI = originalConfigValue;
});
it('should not render the experimental QueryHeader when feature toggle is disabled', async () => {
const mockDatasource = createMockDatasource();
const mockQuery = {
...createMockQuery(),
queryType: AzureQueryType.AzureMonitor,
};
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
await waitFor(() => expect(screen.queryByTestId('azure-monitor-experimental-header')).not.toBeInTheDocument());
});
});
@@ -2,7 +2,6 @@ import { debounce } from 'lodash';
import React, { useCallback, useMemo } from 'react';
import { QueryEditorProps } from '@grafana/data';
import { config } from '@grafana/runtime';
import { Alert, CodeEditor } from '@grafana/ui';
import AzureMonitorDatasource from '../../datasource';
@@ -20,7 +19,6 @@ import NewMetricsQueryEditor from '../MetricsQueryEditor/MetricsQueryEditor';
import { QueryHeader } from '../QueryHeader';
import { Space } from '../Space';
import QueryTypeField from './QueryTypeField';
import usePreparedQuery from './usePreparedQuery';
export type AzureMonitorQueryEditorProps = QueryEditorProps<
@@ -57,10 +55,7 @@ const QueryEditor: React.FC<AzureMonitorQueryEditorProps> = ({
return (
<div data-testid="azure-monitor-query-editor">
{config.featureToggles.azureMonitorExperimentalUI && <QueryHeader query={query} onQueryChange={onQueryChange} />}
{!config.featureToggles.azureMonitorExperimentalUI && (
<QueryTypeField query={query} onQueryChange={onQueryChange} />
)}
<QueryHeader query={query} onQueryChange={onQueryChange} />
<EditorForQueryType
data={data}
@@ -1,45 +0,0 @@
import React, { useCallback } from 'react';
import { SelectableValue } from '@grafana/data';
import { Select } from '@grafana/ui';
import { AzureMonitorQuery, AzureQueryType } from '../../types';
import { Field } from '../Field';
interface QueryTypeFieldProps {
query: AzureMonitorQuery;
onQueryChange: (newQuery: AzureMonitorQuery) => void;
}
const QueryTypeField: React.FC<QueryTypeFieldProps> = ({ query, onQueryChange }) => {
const queryTypes: Array<{ value: AzureQueryType; label: string }> = [
{ value: AzureQueryType.AzureMonitor, label: 'Metrics' },
{ value: AzureQueryType.LogAnalytics, label: 'Logs' },
{ value: AzureQueryType.AzureResourceGraph, label: 'Azure Resource Graph' },
];
const handleChange = useCallback(
(change: SelectableValue<AzureQueryType>) => {
change.value &&
onQueryChange({
...query,
queryType: change.value,
});
},
[onQueryChange, query]
);
return (
<Field label="Service">
<Select
inputId="azure-monitor-query-type-field"
value={query.queryType}
options={queryTypes}
onChange={handleChange}
width={38}
/>
</Field>
);
};
export default QueryTypeField;