From aea6d6448a661011b493743c9d35f6fefd79204b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 8 May 2020 18:28:05 +0300 Subject: [PATCH] [Discover] Deangularize the hits counter and create a react component (#65631) * Deangularize the hits counter and create a react component * Add aria-label to button for accessibility * Add icon to the link button and use EuiText * Remove snapshots and test with findTestSubject * Change toString with String() Co-authored-by: Elastic Machine --- .../public/application/_discover.scss | 10 --- .../public/application/angular/discover.html | 24 ++---- .../hits_counter/hits_counter.test.tsx | 69 +++++++++++++++ .../components/hits_counter/hits_counter.tsx | 83 +++++++++++++++++++ .../hits_counter/hits_counter_directive.ts | 27 ++++++ .../components/hits_counter/index.ts | 21 +++++ .../helpers/format_number_with_commas.ts | 27 ++++++ .../public/application/helpers/index.ts | 1 + .../discover/public/get_inner_angular.ts | 2 + 9 files changed, 236 insertions(+), 28 deletions(-) create mode 100644 src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx create mode 100644 src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx create mode 100644 src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts create mode 100644 src/plugins/discover/public/application/components/hits_counter/index.ts create mode 100644 src/plugins/discover/public/application/helpers/format_number_with_commas.ts diff --git a/src/plugins/discover/public/application/_discover.scss b/src/plugins/discover/public/application/_discover.scss index 8eaa66cf58624..590dbebdf4cfe 100644 --- a/src/plugins/discover/public/application/_discover.scss +++ b/src/plugins/discover/public/application/_discover.scss @@ -38,17 +38,7 @@ discover-app { } .dscResultCount { - text-align: center; padding-top: $euiSizeXS; - padding-left: $euiSizeM; - - .dscResultHits { - padding-left: $euiSizeXS; - } - - > .kuiLink { - padding-left: $euiSizeM; - } } .dscTimechart__header { diff --git a/src/plugins/discover/public/application/angular/discover.html b/src/plugins/discover/public/application/angular/discover.html index b4db89b9275b4..a0f98ea38ef78 100644 --- a/src/plugins/discover/public/application/angular/discover.html +++ b/src/plugins/discover/public/application/angular/discover.html @@ -89,24 +89,12 @@

{{screenTitle}}

-
- {{(hits || 0) | number:0}} - - -
+ +
; + + beforeAll(() => { + props = { + onResetQuery: jest.fn(), + showResetButton: true, + hits: 2, + }; + }); + + it('HitsCounter renders a button by providing the showResetButton property', () => { + component = mountWithIntl(); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(1); + }); + + it('HitsCounter not renders a button when the showResetButton property is false', () => { + component = mountWithIntl( + + ); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(0); + }); + + it('expect to render the number of hits', function() { + component = mountWithIntl(); + const hits = findTestSubject(component, 'discoverQueryHits'); + expect(hits.text()).toBe('2'); + }); + + it('expect to render 1,899 hits if 1899 hits given', function() { + component = mountWithIntl( + + ); + const hits = findTestSubject(component, 'discoverQueryHits'); + expect(hits.text()).toBe('1,899'); + }); + + it('should reset query', function() { + component = mountWithIntl(); + findTestSubject(component, 'resetSavedSearch').simulate('click'); + expect(props.onResetQuery).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx b/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx new file mode 100644 index 0000000000000..1d2cd12877b1c --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx @@ -0,0 +1,83 @@ +/* + * 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 from 'react'; +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { formatNumWithCommas } from '../../helpers'; + +export interface HitsCounterProps { + /** + * the number of query hits + */ + hits: number; + /** + * displays the reset button + */ + showResetButton: boolean; + /** + * resets the query + */ + onResetQuery: () => void; +} + +export function HitsCounter({ hits, showResetButton, onResetQuery }: HitsCounterProps) { + return ( + + + + + {formatNumWithCommas(hits)}{' '} + + + + {showResetButton && ( + + + + + + )} + + + ); +} diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts b/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts new file mode 100644 index 0000000000000..8d45e28370cad --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts @@ -0,0 +1,27 @@ +/* + * 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 { HitsCounter } from './hits_counter'; + +export function createHitsCounterDirective(reactDirective: any) { + return reactDirective(HitsCounter, [ + ['hits', { watchDepth: 'reference' }], + ['showResetButton', { watchDepth: 'reference' }], + ['onResetQuery', { watchDepth: 'reference' }], + ]); +} diff --git a/src/plugins/discover/public/application/components/hits_counter/index.ts b/src/plugins/discover/public/application/components/hits_counter/index.ts new file mode 100644 index 0000000000000..58e7a9eda7f51 --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/index.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export { HitsCounter } from './hits_counter'; +export { createHitsCounterDirective } from './hits_counter_directive'; diff --git a/src/plugins/discover/public/application/helpers/format_number_with_commas.ts b/src/plugins/discover/public/application/helpers/format_number_with_commas.ts new file mode 100644 index 0000000000000..01a010d823d5f --- /dev/null +++ b/src/plugins/discover/public/application/helpers/format_number_with_commas.ts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +const COMMA_SEPARATOR_RE = /(\d)(?=(\d{3})+(?!\d))/g; + +/** + * Converts a number to a string and adds commas + * as thousands separators + */ +export const formatNumWithCommas = (input: number) => + String(input).replace(COMMA_SEPARATOR_RE, '$1,'); diff --git a/src/plugins/discover/public/application/helpers/index.ts b/src/plugins/discover/public/application/helpers/index.ts index 7196c96989e97..3555d24924e80 100644 --- a/src/plugins/discover/public/application/helpers/index.ts +++ b/src/plugins/discover/public/application/helpers/index.ts @@ -18,3 +18,4 @@ */ export { shortenDottedString } from './shorten_dotted_string'; +export { formatNumWithCommas } from './format_number_with_commas'; diff --git a/src/plugins/discover/public/get_inner_angular.ts b/src/plugins/discover/public/get_inner_angular.ts index e7813c43383f9..8c3f4f030688c 100644 --- a/src/plugins/discover/public/get_inner_angular.ts +++ b/src/plugins/discover/public/get_inner_angular.ts @@ -57,6 +57,7 @@ import { createTopNavHelper, } from '../../kibana_legacy/public'; import { createDiscoverSidebarDirective } from './application/components/sidebar'; +import { createHitsCounterDirective } from '././application/components/hits_counter'; import { DiscoverStartPlugins } from './plugin'; /** @@ -151,6 +152,7 @@ export function initializeInnerAngularModule( .directive('fixedScroll', FixedScrollProvider) .directive('renderComplete', createRenderCompleteDirective) .directive('discoverSidebar', createDiscoverSidebarDirective) + .directive('hitsCounter', createHitsCounterDirective) .service('debounce', ['$timeout', DebounceProviderTimeout]); }