diff --git a/dashboards-observability/common/constants/explorer.ts b/dashboards-observability/common/constants/explorer.ts index f09d53412..ee9a666d1 100644 --- a/dashboards-observability/common/constants/explorer.ts +++ b/dashboards-observability/common/constants/explorer.ts @@ -29,7 +29,7 @@ export const TAB_CHART_ID_TXT_PFX = 'main-content-vis-'; export const TAB_EVENT_ID = 'main-content-events'; export const TAB_CHART_ID = 'main-content-vis'; export const HAS_SAVED_TIMESTAMP = 'hasSavedTimestamp'; -export const FILTER_OPTIONS = ['Visualization', 'Query']; +export const FILTER_OPTIONS = ['Visualization', 'Query', 'Metric']; export const SAVED_QUERY = 'savedQuery'; export const SAVED_VISUALIZATION = 'savedVisualization'; export const SAVED_OBJECT_ID = 'savedObjectId'; diff --git a/dashboards-observability/public/components/event_analytics/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap b/dashboards-observability/public/components/event_analytics/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap index ef52659b1..449d99b0f 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap +++ b/dashboards-observability/public/components/event_analytics/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap @@ -2,6 +2,7 @@ exports[`Saved query table component Renders saved query table 1`] = ` + +
+
+ + + +
+ + + Save as Metric + +
+
+
+
+
+
+
`; diff --git a/dashboards-observability/public/components/event_analytics/explorer/save_panel/save_panel.tsx b/dashboards-observability/public/components/event_analytics/explorer/save_panel/save_panel.tsx index 5f132bab9..643cce847 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/save_panel/save_panel.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/save_panel/save_panel.tsx @@ -12,6 +12,9 @@ import { EuiSpacer, EuiFieldText, EuiSwitch, + EuiIconTip, + EuiFlexItem, + EuiToolTip } from '@elastic/eui'; import { useEffect } from 'react'; import { isEmpty, isEqual } from 'lodash'; @@ -130,17 +133,21 @@ export const SavePanel = ({ data-test-subj="eventExplorer__querySaveName" /> - {showOptionList && (isEqual(curVisId, 'line')) && spanValue && ( + {showOptionList && ( <> + - + + {checked && ( <> diff --git a/dashboards-observability/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap b/dashboards-observability/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap index 8af7afe8b..fcaaa6c53 100644 --- a/dashboards-observability/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap +++ b/dashboards-observability/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap @@ -157,6 +157,11 @@ exports[`Saved query table component Renders saved query table 1`] = ` "value": "Query", "view": "Query", }, + Object { + "name": "Metric", + "value": "Metric", + "view": "Metric", + }, ], "type": "field_value_selection", }, @@ -194,6 +199,11 @@ exports[`Saved query table component Renders saved query table 1`] = ` "value": "Query", "view": "Query", }, + Object { + "name": "Metric", + "value": "Metric", + "view": "Metric", + }, ], "type": "field_value_selection", }, @@ -337,6 +347,11 @@ exports[`Saved query table component Renders saved query table 1`] = ` "value": "Query", "view": "Query", }, + Object { + "name": "Metric", + "value": "Metric", + "view": "Metric", + }, ], "type": "field_value_selection", }, @@ -384,6 +399,11 @@ exports[`Saved query table component Renders saved query table 1`] = ` "value": "Query", "view": "Query", }, + Object { + "name": "Metric", + "value": "Metric", + "view": "Metric", + }, ], "type": "field_value_selection", } diff --git a/dashboards-observability/public/components/event_analytics/home/saved_objects_table.tsx b/dashboards-observability/public/components/event_analytics/home/saved_objects_table.tsx index 0588232a5..afe00992f 100644 --- a/dashboards-observability/public/components/event_analytics/home/saved_objects_table.tsx +++ b/dashboards-observability/public/components/event_analytics/home/saved_objects_table.tsx @@ -6,6 +6,7 @@ import React, { useState, useRef } from 'react'; import { EuiLink, EuiInMemoryTable, EuiIcon } from '@elastic/eui'; import { FILTER_OPTIONS } from '../../../../common/constants/explorer'; +import { isEmpty } from 'lodash'; interface savedQueryTableProps { savedHistories: Array; @@ -86,6 +87,14 @@ export function SavedQueryTable({ const isSavedVisualization = h.hasOwnProperty('savedVisualization'); const savedObject = isSavedVisualization ? h.savedVisualization : h.savedQuery; const curType = isSavedVisualization ? 'savedVisualization' : 'savedQuery'; + var subType = ''; + if (isSavedVisualization) { + if (savedObject?.sub_type === 'metric') { + subType = 'Metric' + } else { + subType = savedObject?.sub_type; + } + } const record = { objectId: h.objectId, objectType: curType, @@ -100,7 +109,7 @@ export function SavedQueryTable({ id: h.objectId, data: record, name: savedObject.name, - type: isSavedVisualization ? 'Visualization' : 'Query', + type: isSavedVisualization ? (!isEmpty(subType)) ? subType: 'Visualization' : 'Query', }; }); diff --git a/opensearch-observability/src/test/kotlin/org/opensearch/observability/model/SavedVisualizationTests.kt b/opensearch-observability/src/test/kotlin/org/opensearch/observability/model/SavedVisualizationTests.kt index 568ac15cd..ea694c95d 100644 --- a/opensearch-observability/src/test/kotlin/org/opensearch/observability/model/SavedVisualizationTests.kt +++ b/opensearch-observability/src/test/kotlin/org/opensearch/observability/model/SavedVisualizationTests.kt @@ -32,10 +32,7 @@ internal class SavedVisualizationTests { "KE1Ie34BbsTr-CsB4G6Y", "{\"dataConfig\":\"{}\",\"layoutConfig\":\"{}\"}", "metric", - "hours (h)", - SavedVisualization.SelectedLabels( - listOf(SavedVisualization.Token("avg")) - ) + "hours (h)" ) @Test @@ -54,7 +51,7 @@ internal class SavedVisualizationTests { @Test fun `SavedVisualization should deserialize json object using parser`() { val jsonString = - "{\"name\":\"test-saved-visualization\",\"description\":\"test description\",\"query\":\"source=index | where utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\",\"type\":\"bar\",\"selected_date_range\":{\"start\":\"now/15m\",\"end\":\"now\",\"text\":\"utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\"},\"selected_timestamp\":{\"name\":\"utc_time\",\"type\":\"timestamp\"},\"selected_fields\":{\"text\":\"| fields clientip, bytes, memory, host\",\"tokens\":[{\"name\":\"utc_time\",\"type\":\"timestamp\"}]},\"application_id\":\"KE1Ie34BbsTr-CsB4G6Y\",\"user_configs\":\"{\\\"dataConfig\\\":\\\"{}\\\",\\\"layoutConfig\\\":\\\"{}\\\"}\",\"sub_type\":\"metric\",\"units_of_measure\":\"hours (h)\",\"labels\":[{\"label\":\"avg\"}]}" + "{\"name\":\"test-saved-visualization\",\"description\":\"test description\",\"query\":\"source=index | where utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\",\"type\":\"bar\",\"selected_date_range\":{\"start\":\"now/15m\",\"end\":\"now\",\"text\":\"utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\"},\"selected_timestamp\":{\"name\":\"utc_time\",\"type\":\"timestamp\"},\"selected_fields\":{\"text\":\"| fields clientip, bytes, memory, host\",\"tokens\":[{\"name\":\"utc_time\",\"type\":\"timestamp\"}]},\"application_id\":\"KE1Ie34BbsTr-CsB4G6Y\",\"user_configs\":\"{\\\"dataConfig\\\":\\\"{}\\\",\\\"layoutConfig\\\":\\\"{}\\\"}\",\"sub_type\":\"metric\",\"units_of_measure\":\"hours (h)\"}" val recreatedObject = createObjectFromJsonString(jsonString) { SavedVisualization.parse(it) } assertEquals(sampleSavedVisualization, recreatedObject) } @@ -70,7 +67,7 @@ internal class SavedVisualizationTests { @Test fun `SavedVisualization should safely ignore extra field in json object`() { val jsonString = - "{\"name\":\"test-saved-visualization\",\"description\":\"test description\",\"query\":\"source=index | where utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\",\"type\":\"bar\",\"selected_date_range\":{\"start\":\"now/15m\",\"end\":\"now\",\"text\":\"utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\"},\"selected_timestamp\":{\"name\":\"utc_time\",\"type\":\"timestamp\"},\"selected_fields\":{\"text\":\"| fields clientip, bytes, memory, host\",\"tokens\":[{\"name\":\"utc_time\",\"type\":\"timestamp\"}]},\"application_id\":\"KE1Ie34BbsTr-CsB4G6Y\",\"user_configs\":\"{\\\"dataConfig\\\":\\\"{}\\\",\\\"layoutConfig\\\":\\\"{}\\\"}\",\"sub_type\":\"metric\",\"units_of_measure\":\"hours (h)\",\"labels\":[{\"label\":\"avg\"}]}" + "{\"name\":\"test-saved-visualization\",\"description\":\"test description\",\"query\":\"source=index | where utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\",\"type\":\"bar\",\"selected_date_range\":{\"start\":\"now/15m\",\"end\":\"now\",\"text\":\"utc_time > timestamp('2021-07-01 00:00:00') and utc_time < timestamp('2021-07-02 00:00:00')\"},\"selected_timestamp\":{\"name\":\"utc_time\",\"type\":\"timestamp\"},\"selected_fields\":{\"text\":\"| fields clientip, bytes, memory, host\",\"tokens\":[{\"name\":\"utc_time\",\"type\":\"timestamp\"}]},\"application_id\":\"KE1Ie34BbsTr-CsB4G6Y\",\"user_configs\":\"{\\\"dataConfig\\\":\\\"{}\\\",\\\"layoutConfig\\\":\\\"{}\\\"}\",\"sub_type\":\"metric\",\"units_of_measure\":\"hours (h)\"}" val recreatedObject = createObjectFromJsonString(jsonString) { SavedVisualization.parse(it) } assertEquals(sampleSavedVisualization, recreatedObject) }