From 954e5688bc50ad30fc9c007cf53845a52d6feb23 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 6 May 2020 19:00:27 +0300 Subject: [PATCH 1/5] Deangularize the hits counter and create a react component --- .../public/application/_discover.scss | 10 - .../public/application/angular/discover.html | 24 +- .../__snapshots__/hits_counter.test.tsx.snap | 527 ++++++++++++++++++ .../hits_counter/hits_counter.test.tsx | 69 +++ .../components/hits_counter/hits_counter.tsx | 74 +++ .../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 + 10 files changed, 754 insertions(+), 28 deletions(-) create mode 100644 src/plugins/discover/public/application/components/hits_counter/__snapshots__/hits_counter.test.tsx.snap 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}} - - -
+ +
+ + + + +
+ + + + 2 + + + + +
+ + hits + +
+
+
+
+
+
+
+ +`; + +exports[`hits counter HitsCounter renders a button by providing the showResetButton property 1`] = ` + + + + + +
+ + + + 2 + + + + +
+ + hits + +
+
+ +
+ + + +
+
+
+
+
+
+
+
+`; diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx b/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx new file mode 100644 index 0000000000000..336d71392474c --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx @@ -0,0 +1,69 @@ +/* + * 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 { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { ReactWrapper } from 'enzyme'; +import { HitsCounter, HitsCounterProps } from './hits_counter'; +// @ts-ignore +import { findTestSubject } from '@elastic/eui/lib/test'; + +describe('hits counter', function() { + let props: HitsCounterProps; + let component: ReactWrapper; + + beforeAll(() => { + props = { + onResetQuery: jest.fn(), + showResetButton: true, + hits: 2, + }; + }); + + it('HitsCounter renders a button by providing the showResetButton property', () => { + component = mountWithIntl(); + expect(component).toMatchSnapshot(); + }); + + it('HitsCounter not renders a button when the showResetButton property is false', () => { + component = mountWithIntl( + + ); + expect(component).toMatchSnapshot(); + }); + + 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..854d2f38b2ac7 --- /dev/null +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter.tsx @@ -0,0 +1,74 @@ +/* + * 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 } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +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..410bf24f86900 --- /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) => + input.toString().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]); } From e22ab4e08210871c75fe247b7f317aa47e23ae35 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 7 May 2020 16:13:50 +0300 Subject: [PATCH 2/5] Add aria-label to button for accessibility --- .../__snapshots__/hits_counter.test.tsx.snap | 2 ++ .../components/hits_counter/hits_counter.tsx | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/discover/public/application/components/hits_counter/__snapshots__/hits_counter.test.tsx.snap b/src/plugins/discover/public/application/components/hits_counter/__snapshots__/hits_counter.test.tsx.snap index 0761888766e63..af7c692ff294b 100644 --- a/src/plugins/discover/public/application/components/hits_counter/__snapshots__/hits_counter.test.tsx.snap +++ b/src/plugins/discover/public/application/components/hits_counter/__snapshots__/hits_counter.test.tsx.snap @@ -489,11 +489,13 @@ exports[`hits counter HitsCounter renders a button by providing the showResetBut className="euiFlexItem euiFlexItem--flexGrowZero" > - - - - - - - - - -`; diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx b/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx index 336d71392474c..ae5fbd05b0aaf 100644 --- a/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx +++ b/src/plugins/discover/public/application/components/hits_counter/hits_counter.test.tsx @@ -37,14 +37,14 @@ describe('hits counter', function() { it('HitsCounter renders a button by providing the showResetButton property', () => { component = mountWithIntl(); - expect(component).toMatchSnapshot(); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(1); }); it('HitsCounter not renders a button when the showResetButton property is false', () => { component = mountWithIntl( ); - expect(component).toMatchSnapshot(); + expect(findTestSubject(component, 'resetSavedSearch').length).toBe(0); }); it('expect to render the number of hits', function() { From c0ed9f43dfa9db12282211ad90d5389d555ab20a Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 8 May 2020 12:00:04 +0300 Subject: [PATCH 5/5] Change toString with String() --- .../public/application/helpers/format_number_with_commas.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 410bf24f86900..01a010d823d5f 100644 --- a/src/plugins/discover/public/application/helpers/format_number_with_commas.ts +++ b/src/plugins/discover/public/application/helpers/format_number_with_commas.ts @@ -24,4 +24,4 @@ const COMMA_SEPARATOR_RE = /(\d)(?=(\d{3})+(?!\d))/g; * as thousands separators */ export const formatNumWithCommas = (input: number) => - input.toString().replace(COMMA_SEPARATOR_RE, '$1,'); + String(input).replace(COMMA_SEPARATOR_RE, '$1,');