From d8cf8af2cf9995c11e030e8c406a3229412074a8 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 08:49:41 -0700 Subject: [PATCH 1/9] Set up helper for showing JSON request/response bodies --- .../components/api_logs/utils.test.ts | 21 ++++++++++++++++++- .../app_search/components/api_logs/utils.ts | 8 +++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts index f9b6dcea2cbf3..a8966d6c3bb8b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts @@ -5,7 +5,9 @@ * 2.0. */ -import { getDateString, getStatusColor } from './utils'; +import dedent from 'dedent'; + +import { getDateString, getStatusColor, safeJsonParseAndStringify } from './utils'; describe('getDateString', () => { const mockDate = jest @@ -32,3 +34,20 @@ describe('getStatusColor', () => { expect(getStatusColor(503)).toEqual('danger'); }); }); + +describe('safeJsonParseAndStringify', () => { + it('takes an unformatted JSON string and correctly newlines/indents it', () => { + expect(safeJsonParseAndStringify('{"hello":"world","lorem":{"ipsum":"dolor","sit":"amet"}}')) + .toEqual(dedent`{ + "hello": "world", + "lorem": { + "ipsum": "dolor", + "sit": "amet" + } + }`); + }); + + it('returns the original content if it is not properly formatted JSON', () => { + expect(safeJsonParseAndStringify('{invalid json}')).toEqual('{invalid json}'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts index 3217a1561ce76..b7a9fcbc1cc6f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts @@ -19,3 +19,11 @@ export const getStatusColor = (status: number) => { if (status >= 500) color = 'danger'; return color; }; + +export const safeJsonParseAndStringify = (json: string) => { + try { + return JSON.stringify(JSON.parse(json), null, 2); + } catch (e) { + return json; + } +}; From a57fdb6843378930ca66a8612ae442554e978d6f Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 09:33:09 -0700 Subject: [PATCH 2/9] Set up mock API log obj for tests to use --- .../api_logs/__mocks__/api_log.mock.ts | 17 +++++++++++++++++ .../components/api_logs/api_logs_logic.test.ts | 13 ++----------- 2 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts new file mode 100644 index 0000000000000..6106cb049c7a1 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const mockApiLog = { + timestamp: '1970-01-01T12:00:00.000Z', + http_method: 'POST', + status: 200, + user_agent: 'Mozilla/5.0', + full_request_path: '/api/as/v1/engines/national-parks-demo/search.json', + request_body: '{"query":"test search"}', + response_body: + '{"meta":{"page":{"current":1,"total_pages":0,"total_results":0,"size":20}},"results":[]}', +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts index 7b3ee80668ac7..2eda4c6323fa5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts @@ -6,6 +6,7 @@ */ import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__'; +import { mockApiLog } from './__mocks__/api_log.mock'; import '../../__mocks__/engine_logic.mock'; import { nextTick } from '@kbn/test/jest'; @@ -29,17 +30,7 @@ describe('ApiLogsLogic', () => { }; const MOCK_API_RESPONSE = { - results: [ - { - timestamp: '1970-01-01T12:00:00.000Z', - http_method: 'POST', - status: 200, - user_agent: 'some browser agent string', - full_request_path: '/api/as/v1/engines/national-parks-demo/search.json', - request_body: '{"someMockRequest":"hello"}', - response_body: '{"someMockResponse":"world"}', - }, - ], + results: [mockApiLog, mockApiLog], meta: { page: { current: 1, From bee1976b784e6e4d10a4ee007cccc044054ed165 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 09:34:00 -0700 Subject: [PATCH 3/9] Add ApiLogLogic file for flyout handling --- .../api_logs/api_log/api_log_logic.test.tsx | 57 +++++++++++++++++++ .../api_logs/api_log/api_log_logic.ts | 44 ++++++++++++++ .../components/api_logs/api_log/index.ts | 8 +++ 3 files changed, 109 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx new file mode 100644 index 0000000000000..2b7ca7510e8e1 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogicMounter } from '../../../../__mocks__'; +import { mockApiLog } from '../__mocks__/api_log.mock'; + +import { ApiLogLogic } from './'; + +describe('ApiLogLogic', () => { + const { mount } = new LogicMounter(ApiLogLogic); + + const DEFAULT_VALUES = { + isFlyoutOpen: false, + apiLog: null, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('has expected default values', () => { + mount(); + expect(ApiLogLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('openFlyout', () => { + it('sets isFlyoutOpen to true & sets the current apiLog', () => { + mount({ isFlyoutOpen: false, apiLog: null }); + ApiLogLogic.actions.openFlyout(mockApiLog); + + expect(ApiLogLogic.values).toEqual({ + ...DEFAULT_VALUES, + isFlyoutOpen: true, + apiLog: mockApiLog, + }); + }); + }); + + describe('closeFlyout', () => { + it('sets isFlyoutOpen to false & resets the current apiLog', () => { + mount({ isFlyoutOpen: true, apiLog: mockApiLog }); + ApiLogLogic.actions.closeFlyout(); + + expect(ApiLogLogic.values).toEqual({ + ...DEFAULT_VALUES, + isFlyoutOpen: false, + apiLog: null, + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts new file mode 100644 index 0000000000000..8b7c5f70f605c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { ApiLog } from '../types'; + +interface ApiLogValues { + isFlyoutOpen: boolean; + apiLog: ApiLog | null; +} + +interface ApiLogActions { + openFlyout(apiLog: ApiLog): { apiLog: ApiLog }; + closeFlyout(): void; +} + +export const ApiLogLogic = kea>({ + path: ['enterprise_search', 'app_search', 'api_log_logic'], + actions: () => ({ + openFlyout: (apiLog) => ({ apiLog }), + closeFlyout: true, + }), + reducers: () => ({ + isFlyoutOpen: [ + false, + { + openFlyout: () => true, + closeFlyout: () => false, + }, + ], + apiLog: [ + null, + { + openFlyout: (_, { apiLog }) => apiLog, + closeFlyout: () => null, + }, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts new file mode 100644 index 0000000000000..56b7ffd223b02 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { ApiLogLogic } from './api_log_logic'; From 803c8fbfbc8683927cc4f9b41ccd7242d18f91fd Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 09:35:34 -0700 Subject: [PATCH 4/9] Add ApiLogFlyout component --- .../api_logs/api_log/api_log_flyout.test.tsx | 62 ++++++++ .../api_logs/api_log/api_log_flyout.tsx | 137 ++++++++++++++++++ .../components/api_logs/api_log/index.ts | 1 + 3 files changed, 200 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx new file mode 100644 index 0000000000000..6bebeee80465c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockValues, setMockActions } from '../../../../__mocks__'; +import { mockApiLog } from '../__mocks__/api_log.mock'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiFlyout, EuiBadge } from '@elastic/eui'; + +import { ApiLogFlyout, ApiLogHeading } from './api_log_flyout'; + +describe('ApiLogFlyout', () => { + const values = { + isFlyoutOpen: true, + apiLog: mockApiLog, + }; + const actions = { + closeFlyout: jest.fn(), + }; + + beforeEach(() => { + jest.clearAllMocks(); + setMockValues(values); + setMockActions(actions); + }); + + it('renders', () => { + const wrapper = shallow(); + + expect(wrapper.find('h2').text()).toEqual('Request details'); + expect(wrapper.find(ApiLogHeading).last().dive().find('h3').text()).toEqual('Response body'); + expect(wrapper.find(EuiBadge).prop('children')).toEqual('POST'); + }); + + it('closes the flyout', () => { + const wrapper = shallow(); + + wrapper.find(EuiFlyout).simulate('close'); + expect(actions.closeFlyout).toHaveBeenCalled(); + }); + + it('does not render if the flyout is not open', () => { + setMockValues({ ...values, isFlyoutOpen: false }); + const wrapper = shallow(); + + expect(wrapper.isEmptyRender()).toBe(true); + }); + + it('does not render if a current apiLog has not been set', () => { + setMockValues({ ...values, apiLog: null }); + const wrapper = shallow(); + + expect(wrapper.isEmptyRender()).toBe(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx new file mode 100644 index 0000000000000..b3cc45801786c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { + EuiPortal, + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiBadge, + EuiHealth, + EuiText, + EuiCode, + EuiCodeBlock, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { getStatusColor, safeJsonParseAndStringify } from '../utils'; + +import { ApiLogLogic } from './'; + +export const ApiLogFlyout: React.FC = () => { + const { isFlyoutOpen, apiLog } = useValues(ApiLogLogic); + const { closeFlyout } = useActions(ApiLogLogic); + + if (!isFlyoutOpen) return null; + if (!apiLog) return null; + + return ( + + + + +

+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.flyout.title', { + defaultMessage: 'Request details', + })} +

+
+
+ + + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.methodTitle', { + defaultMessage: 'Method', + })} + +
+ {apiLog.http_method} +
+
+ + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.statusTitle', { + defaultMessage: 'Status', + })} + + {apiLog.status} + + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.timestampTitle', { + defaultMessage: 'Timestamp', + })} + + {apiLog.timestamp} + +
+ + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.userAgentTitle', { + defaultMessage: 'User agent', + })} + + + {apiLog.user_agent} + + + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.requestPathTitle', { + defaultMessage: 'Request path', + })} + + + {apiLog.full_request_path} + + + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.requestBodyTitle', { + defaultMessage: 'Request body', + })} + + + {safeJsonParseAndStringify(apiLog.request_body)} + + + + + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.responseBodyTitle', { + defaultMessage: 'Response body', + })} + + + {safeJsonParseAndStringify(apiLog.response_body)} + +
+
+
+ ); +}; + +export const ApiLogHeading: React.FC = ({ children }) => ( + +

{children}

+
+); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts index 56b7ffd223b02..dcf949d9bf222 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts @@ -5,4 +5,5 @@ * 2.0. */ +export { ApiLogFlyout } from './api_log_flyout'; export { ApiLogLogic } from './api_log_logic'; From 4e42f930bcb1e584189154d1121df2f1e11518c4 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 09:36:12 -0700 Subject: [PATCH 5/9] Update views to load flyout --- .../applications/app_search/components/api_logs/api_logs.tsx | 2 ++ .../applications/app_search/components/api_logs/index.ts | 1 + .../components/engine_overview/components/recent_api_logs.tsx | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx index 8ca15906783f9..4690911fad772 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx @@ -26,6 +26,7 @@ import { Loading } from '../../../shared/loading'; import { LogRetentionCallout, LogRetentionTooltip, LogRetentionOptions } from '../log_retention'; +import { ApiLogFlyout } from './api_log'; import { ApiLogsTable, NewApiEventsPrompt } from './components'; import { API_LOGS_TITLE, RECENT_API_EVENTS } from './constants'; @@ -75,6 +76,7 @@ export const ApiLogs: React.FC = ({ engineBreadcrumb }) => { + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts index 183956e51d8d4..568026dab231f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts @@ -7,5 +7,6 @@ export { API_LOGS_TITLE } from './constants'; export { ApiLogsTable, NewApiEventsPrompt } from './components'; +export { ApiLogFlyout } from './api_log'; export { ApiLogs } from './api_logs'; export { ApiLogsLogic } from './api_logs_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx index 3686f380407e2..18f27c3a1e834 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx @@ -13,7 +13,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { EuiButtonEmptyTo } from '../../../../shared/react_router_helpers'; import { ENGINE_API_LOGS_PATH } from '../../../routes'; -import { ApiLogsLogic, ApiLogsTable, NewApiEventsPrompt } from '../../api_logs'; +import { ApiLogsLogic, ApiLogsTable, NewApiEventsPrompt, ApiLogFlyout } from '../../api_logs'; import { RECENT_API_EVENTS } from '../../api_logs/constants'; import { DataPanel } from '../../data_panel'; import { generateEnginePath } from '../../engine'; @@ -46,6 +46,7 @@ export const RecentApiLogs: React.FC = () => { hasBorder > + ); }; From 930df38b80a65d11472ce3247a290feb8bac29c6 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Thu, 1 Apr 2021 09:36:33 -0700 Subject: [PATCH 6/9] Update table to open flyout --- .../components/api_logs/components/api_logs_table.test.tsx | 3 ++- .../components/api_logs/components/api_logs_table.tsx | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx index 99fce81ca348f..768295ec1389c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx @@ -53,6 +53,7 @@ describe('ApiLogsTable', () => { }; const actions = { onPaginate: jest.fn(), + openFlyout: jest.fn(), }; beforeEach(() => { @@ -86,7 +87,7 @@ describe('ApiLogsTable', () => { expect(wrapper.find(EuiButtonEmpty)).toHaveLength(3); wrapper.find('[data-test-subj="ApiLogsTableDetailsButton"]').first().simulate('click'); - // TODO: API log details flyout + expect(actions.openFlyout).toHaveBeenCalled(); }); it('renders an empty prompt if no items are passed', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx index 8ebcc4350f7fc..5ecf8e1ba3330 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx @@ -22,6 +22,7 @@ import { FormattedRelative } from '@kbn/i18n/react'; import { convertMetaToPagination, handlePageChange } from '../../../../shared/table_pagination'; +import { ApiLogLogic } from '../api_log'; import { ApiLogsLogic } from '../index'; import { ApiLog } from '../types'; import { getStatusColor } from '../utils'; @@ -34,6 +35,7 @@ interface Props { export const ApiLogsTable: React.FC = ({ hasPagination }) => { const { dataLoading, apiLogs, meta } = useValues(ApiLogsLogic); const { onPaginate } = useActions(ApiLogsLogic); + const { openFlyout } = useActions(ApiLogLogic); const columns: Array> = [ { @@ -81,7 +83,7 @@ export const ApiLogsTable: React.FC = ({ hasPagination }) => { size="s" className="apiLogDetailButton" data-test-subj="ApiLogsTableDetailsButton" - // TODO: flyout onclick + onClick={() => openFlyout(apiLog)} > {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.detailsButtonLabel', { defaultMessage: 'Details', From b04020aafebcfcbe61812fc68a497e88454d8b15 Mon Sep 17 00:00:00 2001 From: Constance Date: Fri, 2 Apr 2021 13:11:17 -0700 Subject: [PATCH 7/9] Update x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts --- .../public/applications/app_search/components/api_logs/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts index b7a9fcbc1cc6f..5fab4b0ccb3e5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts @@ -23,7 +23,7 @@ export const getStatusColor = (status: number) => { export const safeJsonParseAndStringify = (json: string) => { try { return JSON.stringify(JSON.parse(json), null, 2); - } catch (e) { + } catch { return json; } }; From 24fc7cfbd3bd418c1691f5c7988a4402dfc003f1 Mon Sep 17 00:00:00 2001 From: Constance Date: Mon, 5 Apr 2021 09:05:57 -0700 Subject: [PATCH 8/9] PR feedback: comments Co-authored-by: Byron Hulcher --- .../applications/app_search/components/api_logs/utils.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts index 5fab4b0ccb3e5..1f78da8dd2075 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts @@ -20,10 +20,12 @@ export const getStatusColor = (status: number) => { return color; }; -export const safeJsonParseAndStringify = (json: string) => { +export const attemptToFormatPossibleJson = (possibleJson: string) => { try { - return JSON.stringify(JSON.parse(json), null, 2); + // it is JSON, we can format it + return JSON.stringify(JSON.parse(possibleJson), null, 2); } catch { - return json; + // it's not JSON, likely a string message, we return it rather than format it + return possibleJson; } }; From 3ca74f6f625b60b16bb6ac0dc7f4a21b9b9b6d86 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Mon, 5 Apr 2021 09:46:33 -0700 Subject: [PATCH 9/9] PR feedback: naming/comments --- .../components/api_logs/api_log/api_log_flyout.tsx | 6 +++--- .../app_search/components/api_logs/utils.test.ts | 8 ++++---- .../applications/app_search/components/api_logs/utils.ts | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx index b3cc45801786c..dd53e997da0f7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx @@ -32,7 +32,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { getStatusColor, safeJsonParseAndStringify } from '../utils'; +import { getStatusColor, attemptToFormatJson } from '../utils'; import { ApiLogLogic } from './'; @@ -112,7 +112,7 @@ export const ApiLogFlyout: React.FC = () => { })} - {safeJsonParseAndStringify(apiLog.request_body)} + {attemptToFormatJson(apiLog.request_body)} @@ -122,7 +122,7 @@ export const ApiLogFlyout: React.FC = () => { })} - {safeJsonParseAndStringify(apiLog.response_body)} + {attemptToFormatJson(apiLog.response_body)} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts index a8966d6c3bb8b..ac464e2af353d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts @@ -7,7 +7,7 @@ import dedent from 'dedent'; -import { getDateString, getStatusColor, safeJsonParseAndStringify } from './utils'; +import { getDateString, getStatusColor, attemptToFormatJson } from './utils'; describe('getDateString', () => { const mockDate = jest @@ -35,9 +35,9 @@ describe('getStatusColor', () => { }); }); -describe('safeJsonParseAndStringify', () => { +describe('attemptToFormatJson', () => { it('takes an unformatted JSON string and correctly newlines/indents it', () => { - expect(safeJsonParseAndStringify('{"hello":"world","lorem":{"ipsum":"dolor","sit":"amet"}}')) + expect(attemptToFormatJson('{"hello":"world","lorem":{"ipsum":"dolor","sit":"amet"}}')) .toEqual(dedent`{ "hello": "world", "lorem": { @@ -48,6 +48,6 @@ describe('safeJsonParseAndStringify', () => { }); it('returns the original content if it is not properly formatted JSON', () => { - expect(safeJsonParseAndStringify('{invalid json}')).toEqual('{invalid json}'); + expect(attemptToFormatJson('{invalid json}')).toEqual('{invalid json}'); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts index 1f78da8dd2075..7e5f19686f13b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts @@ -20,12 +20,12 @@ export const getStatusColor = (status: number) => { return color; }; -export const attemptToFormatPossibleJson = (possibleJson: string) => { +export const attemptToFormatJson = (possibleJson: string) => { try { - // it is JSON, we can format it + // it is JSON, we can format it with newlines/indentation return JSON.stringify(JSON.parse(possibleJson), null, 2); } catch { - // it's not JSON, likely a string message, we return it rather than format it + // if it's not JSON, we return the original content return possibleJson; } };