mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* Create reusable AnalyticsCards component * Update EngineOverview to use new AnalyticsCards component * Update Analytics overview with AnalyticsCards + data * Update QueryDetail with AnalyticsCards + data * Update Analytics overview with AnalyticsChart + data - turns out we do need startDate after all for charts, so I added it back to types * Update QueryDetail with AnalyticsChart + data * [Polish] Dash click and no result lines to match standalone UI Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
57787c36d0
commit
f95d619d53
16 changed files with 312 additions and 56 deletions
|
@ -29,6 +29,15 @@ describe('AnalyticsLogic', () => {
|
|||
dataLoading: true,
|
||||
analyticsUnavailable: false,
|
||||
allTags: [],
|
||||
totalQueries: 0,
|
||||
totalQueriesNoResults: 0,
|
||||
totalClicks: 0,
|
||||
totalQueriesForQuery: 0,
|
||||
queriesPerDay: [],
|
||||
queriesNoResultsPerDay: [],
|
||||
clicksPerDay: [],
|
||||
queriesPerDayForQuery: [],
|
||||
startDate: '',
|
||||
};
|
||||
|
||||
const MOCK_TOP_QUERIES = [
|
||||
|
@ -66,6 +75,7 @@ describe('AnalyticsLogic', () => {
|
|||
const MOCK_ANALYTICS_RESPONSE = {
|
||||
analyticsUnavailable: false,
|
||||
allTags: ['some-tag'],
|
||||
startDate: '1970-01-01',
|
||||
recentQueries: MOCK_RECENT_QUERIES,
|
||||
topQueries: MOCK_TOP_QUERIES,
|
||||
topQueriesNoResults: MOCK_TOP_QUERIES,
|
||||
|
@ -81,6 +91,7 @@ describe('AnalyticsLogic', () => {
|
|||
const MOCK_QUERY_RESPONSE = {
|
||||
analyticsUnavailable: false,
|
||||
allTags: ['some-tag'],
|
||||
startDate: '1970-01-01',
|
||||
totalQueriesForQuery: 50,
|
||||
queriesPerDayForQuery: [25, 0, 25],
|
||||
topClicksForQuery: MOCK_TOP_CLICKS,
|
||||
|
@ -120,7 +131,14 @@ describe('AnalyticsLogic', () => {
|
|||
dataLoading: false,
|
||||
analyticsUnavailable: false,
|
||||
allTags: ['some-tag'],
|
||||
// TODO: more state will get set here in future PRs
|
||||
startDate: '1970-01-01',
|
||||
totalClicks: 1000,
|
||||
totalQueries: 5000,
|
||||
totalQueriesNoResults: 500,
|
||||
queriesPerDay: [10, 50, 100],
|
||||
queriesNoResultsPerDay: [1, 2, 3],
|
||||
clicksPerDay: [0, 10, 50],
|
||||
// TODO: Replace this with ...MOCK_ANALYTICS_RESPONSE once all data is set
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -135,7 +153,10 @@ describe('AnalyticsLogic', () => {
|
|||
dataLoading: false,
|
||||
analyticsUnavailable: false,
|
||||
allTags: ['some-tag'],
|
||||
// TODO: more state will get set here in future PRs
|
||||
startDate: '1970-01-01',
|
||||
totalQueriesForQuery: 50,
|
||||
queriesPerDayForQuery: [25, 0, 25],
|
||||
// TODO: Replace this with ...MOCK_QUERY_RESPONSE once all data is set
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -62,6 +62,61 @@ export const AnalyticsLogic = kea<MakeLogicType<AnalyticsValues, AnalyticsAction
|
|||
onQueryDataLoad: (_, { allTags }) => allTags,
|
||||
},
|
||||
],
|
||||
totalQueries: [
|
||||
0,
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { totalQueries }) => totalQueries,
|
||||
},
|
||||
],
|
||||
totalQueriesNoResults: [
|
||||
0,
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { totalQueriesNoResults }) => totalQueriesNoResults,
|
||||
},
|
||||
],
|
||||
totalClicks: [
|
||||
0,
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { totalClicks }) => totalClicks,
|
||||
},
|
||||
],
|
||||
queriesPerDay: [
|
||||
[],
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { queriesPerDay }) => queriesPerDay,
|
||||
},
|
||||
],
|
||||
queriesNoResultsPerDay: [
|
||||
[],
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { queriesNoResultsPerDay }) => queriesNoResultsPerDay,
|
||||
},
|
||||
],
|
||||
clicksPerDay: [
|
||||
[],
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { clicksPerDay }) => clicksPerDay,
|
||||
},
|
||||
],
|
||||
totalQueriesForQuery: [
|
||||
0,
|
||||
{
|
||||
onQueryDataLoad: (_, { totalQueriesForQuery }) => totalQueriesForQuery,
|
||||
},
|
||||
],
|
||||
queriesPerDayForQuery: [
|
||||
[],
|
||||
{
|
||||
onQueryDataLoad: (_, { queriesPerDayForQuery }) => queriesPerDayForQuery,
|
||||
},
|
||||
],
|
||||
startDate: [
|
||||
'',
|
||||
{
|
||||
onAnalyticsDataLoad: (_, { startDate }) => startDate,
|
||||
onQueryDataLoad: (_, { startDate }) => startDate,
|
||||
},
|
||||
],
|
||||
}),
|
||||
listeners: ({ actions }) => ({
|
||||
loadAnalyticsData: async () => {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { EuiStat } from '@elastic/eui';
|
||||
|
||||
import { AnalyticsCards } from './';
|
||||
|
||||
describe('AnalyticsCards', () => {
|
||||
it('renders', () => {
|
||||
const wrapper = shallow(
|
||||
<AnalyticsCards
|
||||
stats={[
|
||||
{
|
||||
stat: 100,
|
||||
text: 'Red fish',
|
||||
dataTestSubj: 'RedFish',
|
||||
},
|
||||
{
|
||||
stat: 2000,
|
||||
text: 'Blue fish',
|
||||
dataTestSubj: 'BlueFish',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(wrapper.find(EuiStat)).toHaveLength(2);
|
||||
expect(wrapper.find('[data-test-subj="RedFish"]').prop('title')).toEqual(100);
|
||||
expect(wrapper.find('[data-test-subj="RedFish"]').prop('description')).toEqual('Red fish');
|
||||
expect(wrapper.find('[data-test-subj="BlueFish"]').prop('title')).toEqual(2000);
|
||||
expect(wrapper.find('[data-test-subj="BlueFish"]').prop('description')).toEqual('Blue fish');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat } from '@elastic/eui';
|
||||
|
||||
interface Props {
|
||||
stats: Array<{
|
||||
text: string;
|
||||
stat: number;
|
||||
dataTestSubj?: string;
|
||||
}>;
|
||||
}
|
||||
export const AnalyticsCards: React.FC<Props> = ({ stats }) => (
|
||||
<EuiFlexGroup>
|
||||
{stats.map(({ text, stat, dataTestSubj }) => (
|
||||
<EuiFlexItem key={text}>
|
||||
<EuiPanel>
|
||||
<EuiStat
|
||||
title={stat}
|
||||
description={text}
|
||||
titleColor="primary"
|
||||
data-test-subj={dataTestSubj}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
);
|
|
@ -54,6 +54,14 @@ describe('AnalyticsChart', () => {
|
|||
expect(wrapper.find(LineSeries)).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('renders dashed lines', () => {
|
||||
const wrapper = shallow(
|
||||
<AnalyticsChart lines={[{ id: 'dashed 1', data: MOCK_DATA, isDashed: true }]} />
|
||||
);
|
||||
|
||||
expect(wrapper.find(LineSeries).prop('lineSeriesStyle')?.line?.dash).toBeTruthy();
|
||||
});
|
||||
|
||||
it('formats x-axis dates correctly', () => {
|
||||
const wrapper = shallow(<AnalyticsChart lines={[{ id: 'test', data: MOCK_DATA }]} />);
|
||||
const dateFormatter: Function = wrapper.find('#bottom-axis').prop('tickFormat');
|
||||
|
|
|
@ -25,6 +25,7 @@ interface Props {
|
|||
lines: Array<{
|
||||
id: string;
|
||||
data: ChartData;
|
||||
isDashed?: boolean;
|
||||
}>;
|
||||
}
|
||||
export const AnalyticsChart: React.FC<Props> = ({ height = 300, lines }) => {
|
||||
|
@ -39,7 +40,7 @@ export const AnalyticsChart: React.FC<Props> = ({ height = 300, lines }) => {
|
|||
headerFormatter: (tooltip) => moment(tooltip.value).format(TOOLTIP_DATE_FORMAT),
|
||||
}}
|
||||
/>
|
||||
{lines.map(({ id, data }) => (
|
||||
{lines.map(({ id, data, isDashed }) => (
|
||||
<LineSeries
|
||||
key={id}
|
||||
id={id}
|
||||
|
@ -47,6 +48,7 @@ export const AnalyticsChart: React.FC<Props> = ({ height = 300, lines }) => {
|
|||
xAccessor={'x'}
|
||||
yAccessors={['y']}
|
||||
curve={CurveType.CURVE_MONOTONE_X}
|
||||
lineSeriesStyle={isDashed ? { line: { dash: [5, 5] } } : undefined}
|
||||
/>
|
||||
))}
|
||||
<Axis
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { AnalyticsCards } from './analytics_cards';
|
||||
export { AnalyticsChart } from './analytics_chart';
|
||||
export { AnalyticsHeader } from './analytics_header';
|
||||
export { AnalyticsUnavailable } from './analytics_unavailable';
|
||||
|
|
|
@ -25,6 +25,10 @@ export const TOTAL_QUERIES = i18n.translate(
|
|||
'xpack.enterpriseSearch.appSearch.engine.analytics.totalQueries',
|
||||
{ defaultMessage: 'Total queries' }
|
||||
);
|
||||
export const TOTAL_QUERIES_NO_RESULTS = i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.analytics.totalQueriesNoResults',
|
||||
{ defaultMessage: 'Total queries with no results' }
|
||||
);
|
||||
export const TOTAL_CLICKS = i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.analytics.totalClicks',
|
||||
{ defaultMessage: 'Total clicks' }
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
export { ANALYTICS_TITLE } from './constants';
|
||||
export { AnalyticsLogic } from './analytics_logic';
|
||||
export { AnalyticsRouter } from './analytics_router';
|
||||
export { AnalyticsChart } from './components';
|
||||
export { AnalyticsCards, AnalyticsChart } from './components';
|
||||
export { convertToChartData } from './utils';
|
||||
|
|
|
@ -34,8 +34,9 @@ interface RecentQuery {
|
|||
interface BaseData {
|
||||
analyticsUnavailable: boolean;
|
||||
allTags: string[];
|
||||
startDate: string;
|
||||
// NOTE: The API sends us back even more data than this (e.g.,
|
||||
// startDate, endDate, currentTag, logRetentionSettings, query),
|
||||
// endDate, currentTag, logRetentionSettings, query),
|
||||
// but we currently don't need that data in our front-end code,
|
||||
// so I'm opting not to list them in our types
|
||||
}
|
||||
|
|
|
@ -4,15 +4,28 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { setMockValues } from '../../../../__mocks__';
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { AnalyticsCards, AnalyticsChart } from '../components';
|
||||
import { Analytics } from './';
|
||||
|
||||
describe('Analytics overview', () => {
|
||||
it('renders', () => {
|
||||
setMockValues({
|
||||
totalQueries: 3,
|
||||
totalQueriesNoResults: 2,
|
||||
totalClicks: 1,
|
||||
queriesPerDay: [10, 20, 30],
|
||||
queriesNoResultsPerDay: [1, 2, 3],
|
||||
clicksPerDay: [0, 1, 5],
|
||||
startDate: '1970-01-01',
|
||||
});
|
||||
const wrapper = shallow(<Analytics />);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBe(false); // TODO
|
||||
expect(wrapper.find(AnalyticsCards)).toHaveLength(1);
|
||||
expect(wrapper.find(AnalyticsChart)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,13 +5,73 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import { ANALYTICS_TITLE } from '../constants';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
|
||||
import {
|
||||
ANALYTICS_TITLE,
|
||||
TOTAL_QUERIES,
|
||||
TOTAL_QUERIES_NO_RESULTS,
|
||||
TOTAL_CLICKS,
|
||||
} from '../constants';
|
||||
import { AnalyticsLayout } from '../analytics_layout';
|
||||
import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../';
|
||||
|
||||
export const Analytics: React.FC = () => {
|
||||
const {
|
||||
totalQueries,
|
||||
totalQueriesNoResults,
|
||||
totalClicks,
|
||||
queriesPerDay,
|
||||
queriesNoResultsPerDay,
|
||||
clicksPerDay,
|
||||
startDate,
|
||||
} = useValues(AnalyticsLogic);
|
||||
|
||||
return (
|
||||
<AnalyticsLayout isAnalyticsView title={ANALYTICS_TITLE}>
|
||||
<AnalyticsCards
|
||||
stats={[
|
||||
{
|
||||
stat: totalQueries,
|
||||
text: TOTAL_QUERIES,
|
||||
dataTestSubj: 'TotalQueriesCard',
|
||||
},
|
||||
{
|
||||
stat: totalQueriesNoResults,
|
||||
text: TOTAL_QUERIES_NO_RESULTS,
|
||||
dataTestSubj: 'TotalQueriesNoResultsCard',
|
||||
},
|
||||
{
|
||||
stat: totalClicks,
|
||||
text: TOTAL_CLICKS,
|
||||
dataTestSubj: 'TotalClicksCard',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
|
||||
<AnalyticsChart
|
||||
lines={[
|
||||
{
|
||||
id: TOTAL_QUERIES,
|
||||
data: convertToChartData({ startDate, data: queriesPerDay }),
|
||||
},
|
||||
{
|
||||
id: TOTAL_QUERIES_NO_RESULTS,
|
||||
data: convertToChartData({ startDate, data: queriesNoResultsPerDay }),
|
||||
isDashed: true,
|
||||
},
|
||||
{
|
||||
id: TOTAL_CLICKS,
|
||||
data: convertToChartData({ startDate, data: clicksPerDay }),
|
||||
isDashed: true,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
|
||||
<p>TODO: Analytics overview</p>
|
||||
</AnalyticsLayout>
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import '../../../../__mocks__/react_router_history.mock';
|
||||
import { setMockValues } from '../../../../__mocks__';
|
||||
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
@ -12,6 +13,7 @@ import { shallow } from 'enzyme';
|
|||
|
||||
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
|
||||
|
||||
import { AnalyticsCards, AnalyticsChart } from '../components';
|
||||
import { QueryDetail } from './';
|
||||
|
||||
describe('QueryDetail', () => {
|
||||
|
@ -19,6 +21,11 @@ describe('QueryDetail', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
(useParams as jest.Mock).mockReturnValueOnce({ query: 'some-query' });
|
||||
|
||||
setMockValues({
|
||||
totalQueriesForQuery: 100,
|
||||
queriesPerDayForQuery: [0, 5, 10],
|
||||
});
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
|
@ -31,5 +38,8 @@ describe('QueryDetail', () => {
|
|||
'Query',
|
||||
'some-query',
|
||||
]);
|
||||
|
||||
expect(wrapper.find(AnalyticsCards)).toHaveLength(1);
|
||||
expect(wrapper.find(AnalyticsChart)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,12 +6,16 @@
|
|||
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
|
||||
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
|
||||
import { BreadcrumbTrail } from '../../../../shared/kibana_chrome/generate_breadcrumbs';
|
||||
|
||||
import { AnalyticsLayout } from '../analytics_layout';
|
||||
import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../';
|
||||
|
||||
const QUERY_DETAIL_TITLE = i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.analytics.queryDetail.title',
|
||||
|
@ -24,10 +28,41 @@ interface Props {
|
|||
export const QueryDetail: React.FC<Props> = ({ breadcrumbs }) => {
|
||||
const { query } = useParams() as { query: string };
|
||||
|
||||
const { totalQueriesForQuery, queriesPerDayForQuery, startDate } = useValues(AnalyticsLogic);
|
||||
|
||||
return (
|
||||
<AnalyticsLayout isQueryView title={`"${query}"`}>
|
||||
<SetPageChrome trail={[...breadcrumbs, QUERY_DETAIL_TITLE, query]} />
|
||||
|
||||
<AnalyticsCards
|
||||
stats={[
|
||||
{
|
||||
stat: totalQueriesForQuery,
|
||||
text: i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.analytics.queryDetail.cardDescription',
|
||||
{
|
||||
defaultMessage: 'Queries for {queryTitle}',
|
||||
values: { queryTitle: query },
|
||||
}
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
|
||||
<AnalyticsChart
|
||||
lines={[
|
||||
{
|
||||
id: i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.analytics.queryDetail.chartTooltip',
|
||||
{ defaultMessage: 'Queries per day' }
|
||||
),
|
||||
data: convertToChartData({ startDate, data: queriesPerDayForQuery }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
|
||||
<p>TODO: Query detail page</p>
|
||||
</AnalyticsLayout>
|
||||
);
|
||||
|
|
|
@ -7,45 +7,19 @@
|
|||
import { setMockValues } from '../../../../__mocks__/kea.mock';
|
||||
|
||||
import React from 'react';
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { EuiStat } from '@elastic/eui';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { AnalyticsCards } from '../../analytics';
|
||||
import { TotalStats } from './total_stats';
|
||||
|
||||
describe('TotalStats', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.clearAllMocks();
|
||||
it('renders', () => {
|
||||
setMockValues({
|
||||
totalQueries: 11,
|
||||
documentCount: 22,
|
||||
totalClicks: 33,
|
||||
});
|
||||
wrapper = shallow(<TotalStats />);
|
||||
});
|
||||
|
||||
it('renders the total queries stat', () => {
|
||||
expect(wrapper.find('[data-test-subj="TotalQueriesCard"]')).toHaveLength(1);
|
||||
|
||||
const card = wrapper.find(EuiStat).at(0);
|
||||
expect(card.prop('title')).toEqual(11);
|
||||
expect(card.prop('description')).toEqual('Total queries');
|
||||
});
|
||||
|
||||
it('renders the total documents stat', () => {
|
||||
expect(wrapper.find('[data-test-subj="TotalDocumentsCard"]')).toHaveLength(1);
|
||||
|
||||
const card = wrapper.find(EuiStat).at(1);
|
||||
expect(card.prop('title')).toEqual(22);
|
||||
expect(card.prop('description')).toEqual('Total documents');
|
||||
});
|
||||
|
||||
it('renders the total clicks stat', () => {
|
||||
expect(wrapper.find('[data-test-subj="TotalClicksCard"]')).toHaveLength(1);
|
||||
|
||||
const card = wrapper.find(EuiStat).at(2);
|
||||
expect(card.prop('title')).toEqual(33);
|
||||
expect(card.prop('description')).toEqual('Total clicks');
|
||||
const wrapper = shallow(<TotalStats />);
|
||||
expect(wrapper.find(AnalyticsCards)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
import React from 'react';
|
||||
import { useValues } from 'kea';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat } from '@elastic/eui';
|
||||
|
||||
import { TOTAL_QUERIES, TOTAL_DOCUMENTS, TOTAL_CLICKS } from '../../analytics/constants';
|
||||
import { AnalyticsCards } from '../../analytics';
|
||||
|
||||
import { EngineOverviewLogic } from '../';
|
||||
|
||||
|
@ -16,22 +16,24 @@ export const TotalStats: React.FC = () => {
|
|||
const { totalQueries, documentCount, totalClicks } = useValues(EngineOverviewLogic);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel data-test-subj="TotalQueriesCard">
|
||||
<EuiStat title={totalQueries} description={TOTAL_QUERIES} titleColor="primary" />
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel data-test-subj="TotalDocumentsCard">
|
||||
<EuiStat title={documentCount} description={TOTAL_DOCUMENTS} titleColor="primary" />
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel data-test-subj="TotalClicksCard">
|
||||
<EuiStat title={totalClicks} description={TOTAL_CLICKS} titleColor="primary" />
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<AnalyticsCards
|
||||
stats={[
|
||||
{
|
||||
stat: totalQueries,
|
||||
text: TOTAL_QUERIES,
|
||||
dataTestSubj: 'TotalQueriesCard',
|
||||
},
|
||||
{
|
||||
stat: documentCount,
|
||||
text: TOTAL_DOCUMENTS,
|
||||
dataTestSubj: 'TotalDocumentsCard',
|
||||
},
|
||||
{
|
||||
stat: totalClicks,
|
||||
text: TOTAL_CLICKS,
|
||||
dataTestSubj: 'TotalClicksCard',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue