From 9f0de8dc6ce380c89368bff5471973c6dc5cbff9 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Mon, 19 Aug 2019 16:54:28 +0800 Subject: [PATCH] [Inspector Views] [Request View] - Migrate inspector_views to new platform (#43191) * [Inspector Views] [Request View] - Migrate inspector_views to new platform * fix i18n keys * rename scss files * fix PR comments --- .../inspector_views/public/index.scss | 4 +- .../inspector_views/public/register_views.js | 3 - .../public/requests/request_details.js | 125 ----------------- .../public/adapters/request/types.ts | 12 +- src/plugins/inspector/public/plugin.tsx | 4 + .../inspector/public/views/_index.scss | 1 + .../inspector/public/views/index.ts} | 4 +- .../public/views}/requests/_index.scss | 0 .../public/views}/requests/_requests.scss | 0 .../requests/components/details/index.ts} | 24 +--- .../details/req_details_request.tsx | 51 +++++++ .../details/req_details_response.tsx | 54 ++++++++ .../components/details/req_details_stats.tsx} | 64 +++++---- .../requests/components/request_details.tsx | 131 ++++++++++++++++++ .../requests/components/request_selector.tsx} | 124 +++++++++-------- .../requests/components/requests_view.tsx} | 101 ++++++-------- .../views/requests/components/types.ts} | 23 +-- .../inspector/public/views/requests/index.ts | 36 +++++ .../translations/translations/ja-JP.json | 36 ++--- .../translations/translations/zh-CN.json | 36 ++--- 20 files changed, 475 insertions(+), 358 deletions(-) delete mode 100644 src/legacy/core_plugins/inspector_views/public/requests/request_details.js create mode 100644 src/plugins/inspector/public/views/_index.scss rename src/{legacy/core_plugins/inspector_views/public/requests/details/index.js => plugins/inspector/public/views/index.ts} (87%) rename src/{legacy/core_plugins/inspector_views/public => plugins/inspector/public/views}/requests/_index.scss (100%) rename src/{legacy/core_plugins/inspector_views/public => plugins/inspector/public/views}/requests/_requests.scss (100%) rename src/{legacy/core_plugins/inspector_views/public/requests/details/req_details_response.js => plugins/inspector/public/views/requests/components/details/index.ts} (62%) create mode 100644 src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx create mode 100644 src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx rename src/{legacy/core_plugins/inspector_views/public/requests/details/req_details_stats.js => plugins/inspector/public/views/requests/components/details/req_details_stats.tsx} (57%) create mode 100644 src/plugins/inspector/public/views/requests/components/request_details.tsx rename src/{legacy/core_plugins/inspector_views/public/requests/request_selector.js => plugins/inspector/public/views/requests/components/request_selector.tsx} (62%) rename src/{legacy/core_plugins/inspector_views/public/requests/requests_view.js => plugins/inspector/public/views/requests/components/requests_view.tsx} (66%) rename src/{legacy/core_plugins/inspector_views/public/requests/details/req_details_request.js => plugins/inspector/public/views/requests/components/types.ts} (64%) create mode 100644 src/plugins/inspector/public/views/requests/index.ts diff --git a/src/legacy/core_plugins/inspector_views/public/index.scss b/src/legacy/core_plugins/inspector_views/public/index.scss index 2fe162d6c49889..1ee74f17aae539 100644 --- a/src/legacy/core_plugins/inspector_views/public/index.scss +++ b/src/legacy/core_plugins/inspector_views/public/index.scss @@ -8,4 +8,6 @@ // insChart__legend-isLoading @import 'data/index'; -@import 'requests/index'; + +// Temporary reference +@import '../../../../plugins/inspector/public/views/index'; diff --git a/src/legacy/core_plugins/inspector_views/public/register_views.js b/src/legacy/core_plugins/inspector_views/public/register_views.js index 077757773780da..e89ed03b0afea7 100644 --- a/src/legacy/core_plugins/inspector_views/public/register_views.js +++ b/src/legacy/core_plugins/inspector_views/public/register_views.js @@ -18,9 +18,6 @@ */ import { DataView } from './data/data_view'; -import { RequestsView } from './requests/requests_view'; - import { viewRegistry } from 'ui/inspector'; viewRegistry.register(DataView); -viewRegistry.register(RequestsView); diff --git a/src/legacy/core_plugins/inspector_views/public/requests/request_details.js b/src/legacy/core_plugins/inspector_views/public/requests/request_details.js deleted file mode 100644 index 92ef84d6c83bd6..00000000000000 --- a/src/legacy/core_plugins/inspector_views/public/requests/request_details.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { - EuiTab, - EuiTabs, -} from '@elastic/eui'; - -import { - RequestDetailsRequest, - RequestDetailsResponse, - RequestDetailsStats, -} from './details'; -import { i18n } from '@kbn/i18n'; - -const DETAILS = [ - { - name: 'Statistics', - label: i18n.translate('inspectorViews.requests.statisticsTabLabel', { - defaultMessage: 'Statistics' - }), - component: RequestDetailsStats - }, - { - name: 'Request', - label: i18n.translate('inspectorViews.requests.requestTabLabel', { - defaultMessage: 'Request' - }), - component: RequestDetailsRequest - }, - { - name: 'Response', - label: i18n.translate('inspectorViews.requests.responseTabLabel', { - defaultMessage: 'Response' - }), - component: RequestDetailsResponse - }, -]; - -class RequestDetails extends Component { - - state = { - availableDetails: [], - selectedDetail: null, - }; - - static getDerivedStateFromProps(nextProps, prevState) { - const selectedDetail = prevState && prevState.selectedDetail; - const availableDetails = DETAILS.filter(detail => - !detail.component.shouldShow || detail.component.shouldShow(nextProps.request) - ); - // If the previously selected detail is still available we want to stay - // on this tab and not set another selectedDetail. - if (selectedDetail && availableDetails.includes(selectedDetail)) { - return { availableDetails }; - } - - return { - availableDetails: availableDetails, - selectedDetail: availableDetails[0] - }; - } - - selectDetailsTab = (detail) => { - if (detail !== this.state.selectedDetail) { - this.setState({ - selectedDetail: detail - }); - } - }; - - renderDetailTab = (detail) => { - return ( - this.selectDetailsTab(detail)} - data-test-subj={`inspectorRequestDetail${detail.name}`} - > - {detail.label} - - ); - } - - render() { - if (this.state.availableDetails.length === 0) { - return null; - } - const DetailComponent = this.state.selectedDetail.component; - return ( -
- - { this.state.availableDetails.map(this.renderDetailTab) } - - -
- ); - } -} - -RequestDetails.propTypes = { - request: PropTypes.object.isRequired, -}; - -export { RequestDetails }; diff --git a/src/plugins/inspector/public/adapters/request/types.ts b/src/plugins/inspector/public/adapters/request/types.ts index 8718bf09fcb155..0a62df7c8d10c9 100644 --- a/src/plugins/inspector/public/adapters/request/types.ts +++ b/src/plugins/inspector/public/adapters/request/types.ts @@ -52,11 +52,13 @@ export interface RequestParams { } export interface RequestStatistics { - [key: string]: { - label: string; - description?: string; - value: any; - }; + [key: string]: RequestStatistic; +} + +export interface RequestStatistic { + label: string; + description?: string; + value: any; } export interface Response { diff --git a/src/plugins/inspector/public/plugin.tsx b/src/plugins/inspector/public/plugin.tsx index 53a7adde9b3a67..d8ff881beb8dc7 100644 --- a/src/plugins/inspector/public/plugin.tsx +++ b/src/plugins/inspector/public/plugin.tsx @@ -24,6 +24,8 @@ import { InspectorViewRegistry } from './view_registry'; import { Adapters, InspectorOptions, InspectorSession } from './types'; import { InspectorPanel } from './ui/inspector_panel'; +import { RequestsView } from './views'; + export interface Setup { registerView: InspectorViewRegistry['register']; @@ -66,6 +68,8 @@ export class InspectorPublicPlugin implements Plugin { public async setup(core: CoreSetup) { this.views = new InspectorViewRegistry(); + this.views.register(RequestsView); + return { registerView: this.views!.register.bind(this.views), diff --git a/src/plugins/inspector/public/views/_index.scss b/src/plugins/inspector/public/views/_index.scss new file mode 100644 index 00000000000000..43fbc09e921ccc --- /dev/null +++ b/src/plugins/inspector/public/views/_index.scss @@ -0,0 +1 @@ +@import './requests/index'; diff --git a/src/legacy/core_plugins/inspector_views/public/requests/details/index.js b/src/plugins/inspector/public/views/index.ts similarity index 87% rename from src/legacy/core_plugins/inspector_views/public/requests/details/index.js rename to src/plugins/inspector/public/views/index.ts index f183c4923693d0..1f900f81fe145e 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/details/index.js +++ b/src/plugins/inspector/public/views/index.ts @@ -17,6 +17,4 @@ * under the License. */ -export * from './req_details_request'; -export * from './req_details_response'; -export * from './req_details_stats'; +export { RequestsView } from './requests'; diff --git a/src/legacy/core_plugins/inspector_views/public/requests/_index.scss b/src/plugins/inspector/public/views/requests/_index.scss similarity index 100% rename from src/legacy/core_plugins/inspector_views/public/requests/_index.scss rename to src/plugins/inspector/public/views/requests/_index.scss diff --git a/src/legacy/core_plugins/inspector_views/public/requests/_requests.scss b/src/plugins/inspector/public/views/requests/_requests.scss similarity index 100% rename from src/legacy/core_plugins/inspector_views/public/requests/_requests.scss rename to src/plugins/inspector/public/views/requests/_requests.scss diff --git a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_response.js b/src/plugins/inspector/public/views/requests/components/details/index.ts similarity index 62% rename from src/legacy/core_plugins/inspector_views/public/requests/details/req_details_response.js rename to src/plugins/inspector/public/views/requests/components/details/index.ts index 3988237bc79d37..83ab9d8ed8780a 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_response.js +++ b/src/plugins/inspector/public/views/requests/components/details/index.ts @@ -17,24 +17,6 @@ * under the License. */ -import React from 'react'; -import { - EuiCodeBlock, -} from '@elastic/eui'; - -function RequestDetailsResponse(props) { - return ( - - { JSON.stringify(props.request.response.json, null, 2) } - - ); -} - -RequestDetailsResponse.shouldShow = (request) => request.response && request.response.json; - -export { RequestDetailsResponse }; +export { RequestDetailsRequest } from './req_details_request'; +export { RequestDetailsResponse } from './req_details_response'; +export { RequestDetailsStats } from './req_details_stats'; diff --git a/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx b/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx new file mode 100644 index 00000000000000..24412e860f73c5 --- /dev/null +++ b/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { EuiCodeBlock } from '@elastic/eui'; +import { Request } from '../../../../adapters/request/types'; +import { RequestDetailsProps } from '../types'; + +export class RequestDetailsRequest extends Component { + static propTypes = { + request: PropTypes.object.isRequired, + }; + + static shouldShow = (request: Request) => Boolean(request && request.json); + + render() { + const { json } = this.props.request; + + if (!json) { + return null; + } + + return ( + + {JSON.stringify(json, null, 2)} + + ); + } +} diff --git a/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx b/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx new file mode 100644 index 00000000000000..f72cde24854a29 --- /dev/null +++ b/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { EuiCodeBlock } from '@elastic/eui'; +import { Request } from '../../../../adapters/request/types'; +import { RequestDetailsProps } from '../types'; + +export class RequestDetailsResponse extends Component { + static propTypes = { + request: PropTypes.object.isRequired, + }; + + static shouldShow = (request: Request) => + Boolean(RequestDetailsResponse.getResponseJson(request)); + + static getResponseJson = (request: Request) => (request.response ? request.response.json : null); + + render() { + const responseJSON = RequestDetailsResponse.getResponseJson(this.props.request); + + if (!responseJSON) { + return null; + } + + return ( + + {JSON.stringify(responseJSON, null, 2)} + + ); + } +} diff --git a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_stats.js b/src/plugins/inspector/public/views/requests/components/details/req_details_stats.tsx similarity index 57% rename from src/legacy/core_plugins/inspector_views/public/requests/details/req_details_stats.js rename to src/plugins/inspector/public/views/requests/components/details/req_details_stats.tsx index 1a585d2ceefbb2..c58795d09946c8 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_stats.js +++ b/src/plugins/inspector/public/views/requests/components/details/req_details_stats.tsx @@ -28,58 +28,62 @@ import { EuiTableRowCell, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { Request, RequestStatistic } from '../../../../adapters/request/types'; +import { RequestDetailsProps } from '../types'; -class RequestDetailsStats extends Component { - static shouldShow = (request) => !!request.stats && Object.keys(request.stats).length; +// TODO: Replace by property once available +interface RequestDetailsStatRow extends RequestStatistic { + id: string; +} + +export class RequestDetailsStats extends Component { + static propTypes = { + request: PropTypes.object.isRequired, + }; - renderStatRow = (stat) => { + static shouldShow = (request: Request) => + Boolean(request.stats && Object.keys(request.stats).length); + + renderStatRow = (stat: RequestDetailsStatRow) => { return [ - + - { stat.description && + {stat.description ? ( - } - { !stat.description && - - } + ) : ( + + )} {stat.label} {stat.value} - + , ]; }; render() { const { stats } = this.props.request; - const sortedStats = Object.keys(stats).sort().map(id => ({ id, ...stats[id] })); - // TODO: Replace by property once available + + if (!stats) { + return null; + } + + const sortedStats = Object.keys(stats) + .sort() + .map(id => ({ id, ...stats[id] } as RequestDetailsStatRow)); + return ( - - - { sortedStats.map(this.renderStatRow) } - + + {sortedStats.map(this.renderStatRow)} ); } } - -RequestDetailsStats.propTypes = { - request: PropTypes.object.isRequired, -}; - -export { RequestDetailsStats }; diff --git a/src/plugins/inspector/public/views/requests/components/request_details.tsx b/src/plugins/inspector/public/views/requests/components/request_details.tsx new file mode 100644 index 00000000000000..c89800e45d17f6 --- /dev/null +++ b/src/plugins/inspector/public/views/requests/components/request_details.tsx @@ -0,0 +1,131 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { i18n } from '@kbn/i18n'; +import { EuiTab, EuiTabs } from '@elastic/eui'; + +import { RequestDetailsRequest, RequestDetailsResponse, RequestDetailsStats } from './details'; +import { RequestDetailsProps } from './types'; + +interface RequestDetailsState { + availableDetails: DetailViewData[]; + selectedDetail: DetailViewData | null; +} + +export interface DetailViewData { + name: string; + label: string; + component: any; +} + +const DETAILS: DetailViewData[] = [ + { + name: 'Statistics', + label: i18n.translate('inspector.requests.statisticsTabLabel', { + defaultMessage: 'Statistics', + }), + component: RequestDetailsStats, + }, + { + name: 'Request', + label: i18n.translate('inspector.requests.requestTabLabel', { + defaultMessage: 'Request', + }), + component: RequestDetailsRequest, + }, + { + name: 'Response', + label: i18n.translate('inspector.requests.responseTabLabel', { + defaultMessage: 'Response', + }), + component: RequestDetailsResponse, + }, +]; + +export class RequestDetails extends Component { + static propTypes = { + request: PropTypes.object.isRequired, + }; + + state = { + availableDetails: [], + selectedDetail: null, + }; + + static getDerivedStateFromProps(nextProps: RequestDetailsProps, prevState: RequestDetailsState) { + const selectedDetail = prevState && prevState.selectedDetail; + const availableDetails = DETAILS.filter( + (detail: DetailViewData) => + !detail.component.shouldShow || detail.component.shouldShow(nextProps.request) + ); + // If the previously selected detail is still available we want to stay + // on this tab and not set another selectedDetail. + if (selectedDetail && availableDetails.includes(selectedDetail)) { + return { availableDetails }; + } + + return { + availableDetails, + selectedDetail: availableDetails[0], + }; + } + + selectDetailsTab = (detail: DetailViewData) => { + if (detail !== this.state.selectedDetail) { + this.setState({ + selectedDetail: detail, + }); + } + }; + + static getSelectedDetailComponent(detail: DetailViewData | null) { + return detail ? detail.component : null; + } + + renderDetailTab = (detail: DetailViewData) => { + return ( + this.selectDetailsTab(detail)} + data-test-subj={`inspectorRequestDetail${detail.name}`} + > + {detail.label} + + ); + }; + + render() { + const { selectedDetail, availableDetails } = this.state; + const DetailComponent = RequestDetails.getSelectedDetailComponent(selectedDetail); + + if (!availableDetails.length || !DetailComponent) { + return null; + } + + return ( + <> + {this.state.availableDetails.map(this.renderDetailTab)} + + + ); + } +} diff --git a/src/legacy/core_plugins/inspector_views/public/requests/request_selector.js b/src/plugins/inspector/public/views/requests/components/request_selector.tsx similarity index 62% rename from src/legacy/core_plugins/inspector_views/public/requests/request_selector.js rename to src/plugins/inspector/public/views/requests/components/request_selector.tsx index 6801c9e6d6ec78..535ce8ef4b7fc4 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/request_selector.js +++ b/src/plugins/inspector/public/views/requests/components/request_selector.tsx @@ -18,7 +18,9 @@ */ import React, { Component } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; import PropTypes from 'prop-types'; +import { i18n } from '@kbn/i18n'; import { EuiBadge, @@ -33,29 +35,43 @@ import { EuiToolTip, } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; +import { RequestStatus } from '../../../adapters'; +import { Request } from '../../../adapters/request/types'; + +interface RequestSelectorState { + isPopoverOpen: boolean; +} + +interface RequestSelectorProps { + requests: Request[]; + selectedRequest: Request; + onRequestChanged: Function; +} -import { RequestStatus } from 'ui/inspector/adapters'; +export class RequestSelector extends Component { + static propTypes = { + requests: PropTypes.array.isRequired, + selectedRequest: PropTypes.object.isRequired, + onRequestChanged: PropTypes.func, + }; -class RequestSelector extends Component { state = { isPopoverOpen: false, }; togglePopover = () => { - this.setState((prevState) => ({ + this.setState((prevState: RequestSelectorState) => ({ isPopoverOpen: !prevState.isPopoverOpen, })); - } + }; closePopover = () => { this.setState({ isPopoverOpen: false, }); - } + }; - renderRequestDropdownItem = (request, index) => { + renderRequestDropdownItem = (request: Request, index: number) => { const hasFailed = request.status === RequestStatus.ERROR; const inProgress = request.status === RequestStatus.PENDING; @@ -73,23 +89,24 @@ class RequestSelector extends Component { > {request.name} - { hasFailed && } - { inProgress && + + {hasFailed && ( + + )} + + {inProgress && ( - } + )} ); - } + }; renderRequestDropdown() { const button = ( @@ -124,78 +141,71 @@ class RequestSelector extends Component { render() { const { selectedRequest, requests } = this.props; + return ( - - + + - + - {requests.length <= 1 && -
+ {requests.length <= 1 && ( +
{selectedRequest.name}
- } + )} {requests.length > 1 && this.renderRequestDropdown()} - { selectedRequest.status !== RequestStatus.PENDING && + {selectedRequest.status !== RequestStatus.PENDING && ( : + title={ + selectedRequest.status === RequestStatus.OK ? ( + + ) : ( + + ) + } + content={ } - content={} > - - } - { selectedRequest.status === RequestStatus.PENDING && + )} + {selectedRequest.status === RequestStatus.PENDING && ( - } + )} ); } } - -RequestSelector.propTypes = { - requests: PropTypes.array.isRequired, - selectedRequest: PropTypes.object.isRequired, -}; - -export { RequestSelector }; diff --git a/src/legacy/core_plugins/inspector_views/public/requests/requests_view.js b/src/plugins/inspector/public/views/requests/components/requests_view.tsx similarity index 66% rename from src/legacy/core_plugins/inspector_views/public/requests/requests_view.js rename to src/plugins/inspector/public/views/requests/components/requests_view.tsx index a949b2ebe6ea1e..01ae5e739c93ba 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/requests_view.js +++ b/src/plugins/inspector/public/views/requests/components/requests_view.tsx @@ -19,60 +19,67 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { - EuiEmptyPrompt, - EuiSpacer, - EuiText, - EuiTextColor, -} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiEmptyPrompt, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui'; -import { RequestStatus } from 'ui/inspector/adapters'; +import { RequestStatus } from '../../../adapters'; +import { Request } from '../../../adapters/request/types'; +import { InspectorViewProps } from '../../../types'; import { RequestSelector } from './request_selector'; import { RequestDetails } from './request_details'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -class RequestsViewComponent extends Component { +interface RequestSelectorState { + requests: Request[]; + request: Request; +} + +export class RequestsViewComponent extends Component { + static propTypes = { + adapters: PropTypes.object.isRequired, + title: PropTypes.string.isRequired, + }; - constructor(props) { + constructor(props: InspectorViewProps) { super(props); + props.adapters.requests.on('change', this._onRequestsChange); const requests = props.adapters.requests.getRequests(); this.state = { - requests: requests, - request: requests.length ? requests[0] : null + requests, + request: requests.length ? requests[0] : null, }; } _onRequestsChange = () => { const requests = this.props.adapters.requests.getRequests(); - const newState = { requests }; + const newState = { requests } as RequestSelectorState; + if (!requests.includes(this.state.request)) { newState.request = requests.length ? requests[0] : null; } this.setState(newState); - } + }; - selectRequest = (request) => { + selectRequest = (request: Request) => { if (request !== this.state.request) { this.setState({ request }); } - } + }; componentWillUnmount() { this.props.adapters.requests.removeListener('change', this._onRequestsChange); } - renderEmptyRequests() { + static renderEmptyRequests() { return ( @@ -81,13 +88,13 @@ class RequestsViewComponent extends Component {

@@ -100,11 +107,11 @@ class RequestsViewComponent extends Component { render() { if (!this.state.requests || !this.state.requests.length) { - return this.renderEmptyRequests(); + return RequestsViewComponent.renderEmptyRequests(); } const failedCount = this.state.requests.filter( - req => req.status === RequestStatus.ERROR + (req: Request) => req.status === RequestStatus.ERROR ).length; return ( @@ -112,64 +119,44 @@ class RequestsViewComponent extends Component {

0 ? ( - ) : '' - ) + ) : ( + '' + ), }} />

- + - - { this.state.request && this.state.request.description && + + + {this.state.request && this.state.request.description && (

{this.state.request.description}

- } + )} + - { this.state.request && - - } + + {this.state.request && } ); } } - -RequestsViewComponent.propTypes = { - adapters: PropTypes.object.isRequired, -}; - -const RequestsView = { - title: i18n.translate('inspectorViews.requests.requestsTitle', { - defaultMessage: 'Requests' - }), - order: 20, - help: i18n.translate('inspectorViews.requests.requestsDescriptionTooltip', { - defaultMessage: 'View the requests that collected the data' - }), - shouldShow(adapters) { - return Boolean(adapters.requests); - }, - component: RequestsViewComponent -}; - -export { RequestsView }; diff --git a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_request.js b/src/plugins/inspector/public/views/requests/components/types.ts similarity index 64% rename from src/legacy/core_plugins/inspector_views/public/requests/details/req_details_request.js rename to src/plugins/inspector/public/views/requests/components/types.ts index 08e3052b2e22c4..ebc3b41e410196 100644 --- a/src/legacy/core_plugins/inspector_views/public/requests/details/req_details_request.js +++ b/src/plugins/inspector/public/views/requests/components/types.ts @@ -16,25 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import { Request } from '../../../adapters/request/types'; -import React from 'react'; -import { - EuiCodeBlock, -} from '@elastic/eui'; - -function RequestDetailsRequest(props) { - return ( - - { JSON.stringify(props.request.json, null, 2) } - - ); +export interface RequestDetailsProps { + request: Request; } - -RequestDetailsRequest.shouldShow = (request) => !!request.json; - -export { RequestDetailsRequest }; diff --git a/src/plugins/inspector/public/views/requests/index.ts b/src/plugins/inspector/public/views/requests/index.ts new file mode 100644 index 00000000000000..14ee38b415d1f6 --- /dev/null +++ b/src/plugins/inspector/public/views/requests/index.ts @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { i18n } from '@kbn/i18n'; + +import { RequestsViewComponent } from './components/requests_view'; +import { Adapters, InspectorViewDescription } from '../../types'; + +export const RequestsView: InspectorViewDescription = { + title: i18n.translate('inspector.requests.requestsTitle', { + defaultMessage: 'Requests', + }), + order: 20, + help: i18n.translate('inspector.requests.requestsDescriptionTooltip', { + defaultMessage: 'View the requests that collected the data', + }), + shouldShow(adapters: Adapters) { + return Boolean(adapters.requests); + }, + component: RequestsViewComponent, +}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ec9f1387ebef63..d9fa07c4d4d049 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -887,24 +887,24 @@ "inspectorViews.data.noDataAvailableTitle": "利用可能なデータがありません", "inspectorViews.data.rawCSVButtonLabel": "CSV", "inspectorViews.data.rawCSVButtonTooltip": "日付をタイムスタンプとしてなど、提供されたデータをそのままダウンロードします", - "inspectorViews.requests.descriptionRowIconAriaLabel": "説明", - "inspectorViews.requests.failedLabel": " (失敗)", - "inspectorViews.requests.noRequestsLoggedDescription.elementHasNotLoggedAnyRequestsText": "エレメントが (まだ) リクエストを記録していません。", - "inspectorViews.requests.noRequestsLoggedDescription.whatDoesItUsuallyMeanText": "これは通常、データを取得する必要がないか、エレメントがまだデータの取得を開始していないことを意味します。", - "inspectorViews.requests.noRequestsLoggedTitle": "リクエストが記録されていません", - "inspectorViews.requests.requestFailedTooltipTitle": "リクエストに失敗しました", - "inspectorViews.requests.requestInProgressAriaLabel": "リクエスト進行中", - "inspectorViews.requests.requestLabel": "リクエスト", - "inspectorViews.requests.requestsDescriptionTooltip": "データを収集したリクエストを表示します", - "inspectorViews.requests.requestsTitle": "リクエスト", - "inspectorViews.requests.requestSucceededTooltipTitle": "リクエスト成功", - "inspectorViews.requests.requestTabLabel": "リクエスト", - "inspectorViews.requests.requestTimeLabel": "{requestTime}ms", - "inspectorViews.requests.requestTooltipDescription": "リクエストの合計所要時間です。", - "inspectorViews.requests.requestWasMadeDescription": "{requestsCount, plural, one {# リクエストが} other {# リクエストが} } 行われました{failedRequests}", - "inspectorViews.requests.requestWasMadeDescription.requestHadFailureText": "、{failedCount} 件に失敗がありました", - "inspectorViews.requests.responseTabLabel": "応答", - "inspectorViews.requests.statisticsTabLabel": "統計", + "inspector.requests.descriptionRowIconAriaLabel": "説明", + "inspector.requests.failedLabel": " (失敗)", + "inspector.requests.noRequestsLoggedDescription.elementHasNotLoggedAnyRequestsText": "エレメントが (まだ) リクエストを記録していません。", + "inspector.requests.noRequestsLoggedDescription.whatDoesItUsuallyMeanText": "これは通常、データを取得する必要がないか、エレメントがまだデータの取得を開始していないことを意味します。", + "inspector.requests.noRequestsLoggedTitle": "リクエストが記録されていません", + "inspector.requests.requestFailedTooltipTitle": "リクエストに失敗しました", + "inspector.requests.requestInProgressAriaLabel": "リクエスト進行中", + "inspector.requests.requestLabel": "リクエスト", + "inspector.requests.requestsDescriptionTooltip": "データを収集したリクエストを表示します", + "inspector.requests.requestsTitle": "リクエスト", + "inspector.requests.requestSucceededTooltipTitle": "リクエスト成功", + "inspector.requests.requestTabLabel": "リクエスト", + "inspector.requests.requestTimeLabel": "{requestTime}ms", + "inspector.requests.requestTooltipDescription": "リクエストの合計所要時間です。", + "inspector.requests.requestWasMadeDescription": "{requestsCount, plural, one {# リクエストが} other {# リクエストが} } 行われました{failedRequests}", + "inspector.requests.requestWasMadeDescription.requestHadFailureText": "、{failedCount} 件に失敗がありました", + "inspector.requests.responseTabLabel": "応答", + "inspector.requests.statisticsTabLabel": "統計", "interpreter.function.visDimension.accessor.help": "使用するデータセット内の列 (列インデックスまたは列名)", "interpreter.function.visDimension.error.accessor": "入力された列名は無効です。", "interpreter.function.visDimension.help": "visConfig ディメンションオブジェクトを生成します", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 5b1261daf726b5..4cb675289354a3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -887,24 +887,24 @@ "inspectorViews.data.noDataAvailableTitle": "没有可用数据", "inspectorViews.data.rawCSVButtonLabel": "原始 CSV", "inspectorViews.data.rawCSVButtonTooltip": "按原样下载数据,例如将日期作为时间戳下载", - "inspectorViews.requests.descriptionRowIconAriaLabel": "描述", - "inspectorViews.requests.failedLabel": " (失败)", - "inspectorViews.requests.noRequestsLoggedDescription.elementHasNotLoggedAnyRequestsText": "该元素尚未记录任何请求。", - "inspectorViews.requests.noRequestsLoggedDescription.whatDoesItUsuallyMeanText": "这通常表示无需提取任何数据,或该元素尚未开始提取数据。", - "inspectorViews.requests.noRequestsLoggedTitle": "未记录任何请求", - "inspectorViews.requests.requestFailedTooltipTitle": "请求失败", - "inspectorViews.requests.requestInProgressAriaLabel": "请求进行中", - "inspectorViews.requests.requestLabel": "请求:", - "inspectorViews.requests.requestsDescriptionTooltip": "查看已收集数据的请求", - "inspectorViews.requests.requestsTitle": "请求", - "inspectorViews.requests.requestSucceededTooltipTitle": "请求成功", - "inspectorViews.requests.requestTabLabel": "请求", - "inspectorViews.requests.requestTimeLabel": "{requestTime}ms", - "inspectorViews.requests.requestTooltipDescription": "请求所花费的总时间。", - "inspectorViews.requests.requestWasMadeDescription": "{requestsCount, plural, one {# 个请求已} other {# 个请求已} }发出{failedRequests}", - "inspectorViews.requests.requestWasMadeDescription.requestHadFailureText": ",{failedCount} 个失败", - "inspectorViews.requests.responseTabLabel": "响应", - "inspectorViews.requests.statisticsTabLabel": "统计信息", + "inspector.requests.descriptionRowIconAriaLabel": "描述", + "inspector.requests.failedLabel": " (失败)", + "inspector.requests.noRequestsLoggedDescription.elementHasNotLoggedAnyRequestsText": "该元素尚未记录任何请求。", + "inspector.requests.noRequestsLoggedDescription.whatDoesItUsuallyMeanText": "这通常表示无需提取任何数据,或该元素尚未开始提取数据。", + "inspector.requests.noRequestsLoggedTitle": "未记录任何请求", + "inspector.requests.requestFailedTooltipTitle": "请求失败", + "inspector.requests.requestInProgressAriaLabel": "请求进行中", + "inspector.requests.requestLabel": "请求:", + "inspector.requests.requestsDescriptionTooltip": "查看已收集数据的请求", + "inspector.requests.requestsTitle": "请求", + "inspector.requests.requestSucceededTooltipTitle": "请求成功", + "inspector.requests.requestTabLabel": "请求", + "inspector.requests.requestTimeLabel": "{requestTime}ms", + "inspector.requests.requestTooltipDescription": "请求所花费的总时间。", + "inspector.requests.requestWasMadeDescription": "{requestsCount, plural, one {# 个请求已} other {# 个请求已} }发出{failedRequests}", + "inspector.requests.requestWasMadeDescription.requestHadFailureText": ",{failedCount} 个失败", + "inspector.requests.responseTabLabel": "响应", + "inspector.requests.statisticsTabLabel": "统计信息", "interpreter.function.visDimension.accessor.help": "数据集中要使用的列(列索引或列名称)", "interpreter.function.visDimension.error.accessor": "提供的列名称无效", "interpreter.function.visDimension.help": "生成 visConfig 维度对象",