Skip to content

Commit dcda4b8

Browse files
authored
Fix bugs in UI and refactor code (#15)
Signed-off-by: Chenyang Ji <[email protected]>
1 parent 4e7549d commit dcda4b8

File tree

10 files changed

+163
-88
lines changed

10 files changed

+163
-88
lines changed

Diff for: common/constants.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
export const TIMESTAMP = 'Timestamp';
7+
export const LATENCY = 'Latency';
8+
export const CPU_TIME = 'CPU Time';
9+
export const MEMORY_USAGE = 'Memory Usage';
10+
export const INDICES = 'Indices';
11+
export const SEARCH_TYPE = 'Search type';
12+
export const NODE_ID = 'Coordinator node ID';
13+
export const TOTAL_SHARDS = 'Total shards';

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@testing-library/dom": "^8.11.3",
4444
"@testing-library/user-event": "^14.4.3",
4545
"@types/react-dom": "^16.9.8",
46+
"@types/object-hash": "^3.0.0",
4647
"@types/react-router-dom": "^5.3.2",
4748
"cypress": "9.5.4",
4849
"cypress-real-events": "1.7.6",

Diff for: public/components/__snapshots__/app.test.tsx.snap

+7-7
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
452452
aria-live="polite"
453453
aria-sort="none"
454454
class="euiTableHeaderCell"
455-
data-test-subj="tableHeaderCell_latency_1"
455+
data-test-subj="tableHeaderCell_measurements_1"
456456
role="columnheader"
457457
scope="col"
458458
>
@@ -477,7 +477,7 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
477477
aria-live="polite"
478478
aria-sort="none"
479479
class="euiTableHeaderCell"
480-
data-test-subj="tableHeaderCell_cpu_2"
480+
data-test-subj="tableHeaderCell_measurements_2"
481481
role="columnheader"
482482
scope="col"
483483
>
@@ -491,9 +491,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
491491
>
492492
<span
493493
class="euiTableCellContent__text"
494-
title="CPU usage"
494+
title="CPU Time"
495495
>
496-
CPU usage
496+
CPU Time
497497
</span>
498498
</span>
499499
</button>
@@ -502,7 +502,7 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
502502
aria-live="polite"
503503
aria-sort="none"
504504
class="euiTableHeaderCell"
505-
data-test-subj="tableHeaderCell_memory_3"
505+
data-test-subj="tableHeaderCell_measurements_3"
506506
role="columnheader"
507507
scope="col"
508508
>
@@ -516,9 +516,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
516516
>
517517
<span
518518
class="euiTableCellContent__text"
519-
title="Memory"
519+
title="Memory Usage"
520520
>
521-
Memory
521+
Memory Usage
522522
</span>
523523
</span>
524524
</button>

Diff for: public/pages/Configuration/Configuration.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
EuiTitle,
2424
} from '@elastic/eui';
2525
import { useHistory, useLocation } from 'react-router-dom';
26-
import { CoreStart } from '../../../../../src/core/public';
26+
import { CoreStart } from 'opensearch-dashboards/public';
2727
import { QUERY_INSIGHTS, MetricSettings } from '../TopNQueries/TopNQueries';
2828

2929
const Configuration = ({

Diff for: public/pages/QueryDetails/Components/QuerySummary.tsx

+39-49
Original file line numberDiff line numberDiff line change
@@ -5,68 +5,58 @@
55

66
import React from 'react';
77
import { EuiFlexGrid, EuiFlexItem, EuiHorizontalRule, EuiPanel, EuiText } from '@elastic/eui';
8+
import { SearchQueryRecord } from '../../../../types/types';
9+
import {
10+
CPU_TIME,
11+
INDICES,
12+
LATENCY,
13+
MEMORY_USAGE,
14+
NODE_ID,
15+
SEARCH_TYPE,
16+
TIMESTAMP,
17+
TOTAL_SHARDS,
18+
} from '../../../../common/constants';
819

9-
const QuerySummary = ({ query }: { query: any }) => {
20+
// Panel component for displaying query detail values
21+
const PanelItem = ({ label, value }: { label: string; value: string | number }) => (
22+
<EuiFlexItem>
23+
<EuiText size="xs">
24+
<h4>{label}</h4>
25+
</EuiText>
26+
<EuiText size="xs">{value}</EuiText>
27+
</EuiFlexItem>
28+
);
29+
30+
const QuerySummary = ({ query }: { query: SearchQueryRecord }) => {
1031
const convertTime = (unixTime: number) => {
1132
const date = new Date(unixTime);
1233
const loc = date.toDateString().split(' ');
1334
return `${loc[1]} ${loc[2]}, ${loc[3]} @ ${date.toLocaleTimeString('en-US')}`;
1435
};
36+
// eslint-disable-next-line @typescript-eslint/naming-convention
37+
const { timestamp, measurements, indices, search_type, node_id, total_shards } = query;
1538
return (
1639
<EuiPanel>
1740
<EuiText size="xs">
1841
<h2>Summary</h2>
1942
</EuiText>
2043
<EuiHorizontalRule margin="m" />
2144
<EuiFlexGrid columns={4}>
22-
<EuiFlexItem>
23-
<EuiText size="xs">
24-
<h4>Timestamp</h4>
25-
</EuiText>
26-
<EuiText size="xs">{convertTime(query.timestamp)}</EuiText>
27-
</EuiFlexItem>
28-
<EuiFlexItem>
29-
<EuiText size="xs">
30-
<h4>Latency</h4>
31-
</EuiText>
32-
<EuiText size="xs">{`${query.latency} ms`}</EuiText>
33-
</EuiFlexItem>
34-
<EuiFlexItem>
35-
<EuiText size="xs">
36-
<h4>CPU Usage</h4>
37-
</EuiText>
38-
<EuiText size="xs">{`${query.cpu} ns`}</EuiText>
39-
</EuiFlexItem>
40-
<EuiFlexItem>
41-
<EuiText size="xs">
42-
<h4>Memory</h4>
43-
</EuiText>
44-
<EuiText size="xs">{`${query.memory} B`}</EuiText>
45-
</EuiFlexItem>
46-
<EuiFlexItem>
47-
<EuiText size="xs">
48-
<h4>Indexes</h4>
49-
</EuiText>
50-
<EuiText size="xs">{query.indices.toString()}</EuiText>
51-
</EuiFlexItem>
52-
<EuiFlexItem>
53-
<EuiText size="xs">
54-
<h4>Search type</h4>
55-
</EuiText>
56-
<EuiText size="xs">{query.search_type.replaceAll('_', ' ')}</EuiText>
57-
</EuiFlexItem>
58-
<EuiFlexItem>
59-
<EuiText size="xs">
60-
<h4>Coordinator node ID</h4>
61-
</EuiText>
62-
<EuiText size="xs">{query.node_id}</EuiText>
63-
</EuiFlexItem>
64-
<EuiFlexItem>
65-
<EuiText size="xs">
66-
<h4>Total shards</h4>
67-
</EuiText>
68-
<EuiText size="xs">{query.total_shards}</EuiText>
69-
</EuiFlexItem>
45+
<PanelItem label={TIMESTAMP} value={convertTime(timestamp)} />
46+
<PanelItem label={LATENCY} value={`${measurements.latency?.number ?? 'N/A'} ms`} />
47+
<PanelItem
48+
label={CPU_TIME}
49+
value={
50+
measurements.cpu?.number !== undefined
51+
? `${measurements.cpu.number / 1000000} ms`
52+
: 'N/A'
53+
}
54+
/>
55+
<PanelItem label={MEMORY_USAGE} value={`${measurements.memory?.number ?? 'N/A'} B`} />
56+
<PanelItem label={INDICES} value={indices.toString()} />
57+
<PanelItem label={SEARCH_TYPE} value={search_type.replaceAll('_', ' ')} />
58+
<PanelItem label={NODE_ID} value={node_id} />
59+
<PanelItem label={TOTAL_SHARDS} value={total_shards} />
7060
</EuiFlexGrid>
7161
</EuiPanel>
7262
);

Diff for: public/pages/QueryDetails/QueryDetails.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from '@elastic/eui';
2020
import hash from 'object-hash';
2121
import { useParams, useHistory, useLocation } from 'react-router-dom';
22-
import { CoreStart } from '../../../../../src/core/public';
22+
import { CoreStart } from 'opensearch-dashboards/public';
2323
import QuerySummary from './Components/QuerySummary';
2424
import { QUERY_INSIGHTS } from '../TopNQueries/TopNQueries';
2525

Diff for: public/pages/QueryInsights/QueryInsights.tsx

+41-27
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,22 @@ import React, { useEffect, useState } from 'react';
77
import { EuiBasicTableColumn, EuiInMemoryTable, EuiLink, EuiSuperDatePicker } from '@elastic/eui';
88
import { useHistory, useLocation } from 'react-router-dom';
99
import hash from 'object-hash';
10-
import { CoreStart } from '../../../../../src/core/public';
10+
import { CoreStart } from 'opensearch-dashboards/public';
1111
import { QUERY_INSIGHTS } from '../TopNQueries/TopNQueries';
12+
import { SearchQueryRecord } from '../../../types/types';
13+
import {
14+
CPU_TIME,
15+
INDICES,
16+
LATENCY,
17+
MEMORY_USAGE,
18+
NODE_ID,
19+
SEARCH_TYPE,
20+
TIMESTAMP,
21+
TOTAL_SHARDS,
22+
} from '../../../common/constants';
1223

1324
const TIMESTAMP_FIELD = 'timestamp';
14-
const LATENCY_FIELD = 'latency';
15-
const CPU_FIELD = 'cpu';
16-
const MEMORY_FIELD = 'memory';
25+
const MEASUREMENTS_FIELD = 'measurements';
1726
const INDICES_FIELD = 'indices';
1827
const SEARCH_TYPE_FIELD = 'search_type';
1928
const NODE_ID_FIELD = 'node_id';
@@ -29,7 +38,7 @@ const QueryInsights = ({
2938
currEnd,
3039
core,
3140
}: {
32-
queries: any[];
41+
queries: SearchQueryRecord[];
3342
loading: boolean;
3443
onTimeChange: any;
3544
recentlyUsedRanges: any[];
@@ -63,7 +72,7 @@ const QueryInsights = ({
6372
const cols: Array<EuiBasicTableColumn<any>> = [
6473
{
6574
// Make into flyout instead?
66-
name: 'Timestamp',
75+
name: TIMESTAMP,
6776
render: (query: any) => {
6877
return (
6978
<span>
@@ -77,51 +86,58 @@ const QueryInsights = ({
7786
truncateText: true,
7887
},
7988
{
80-
field: LATENCY_FIELD,
81-
name: 'Latency',
82-
render: (latency: number) =>
83-
typeof latency !== 'undefined' ? `${latency} ms` : `${METRIC_DEFAULT_MSG}`,
89+
field: MEASUREMENTS_FIELD,
90+
name: LATENCY,
91+
render: (measurements: any) => {
92+
const latencyValue = measurements?.latency?.number;
93+
return latencyValue !== undefined ? `${latencyValue} ms` : METRIC_DEFAULT_MSG;
94+
},
8495
sortable: true,
8596
truncateText: true,
8697
},
8798
{
88-
field: CPU_FIELD,
89-
name: 'CPU usage',
90-
render: (cpu: number) => (typeof cpu !== 'undefined' ? `${cpu} ns` : `${METRIC_DEFAULT_MSG}`),
99+
field: MEASUREMENTS_FIELD,
100+
name: CPU_TIME,
101+
render: (measurements: { cpu?: { number?: number } }) => {
102+
const cpuValue = measurements?.cpu?.number;
103+
return cpuValue !== undefined ? `${cpuValue / 1000000} ms` : METRIC_DEFAULT_MSG;
104+
},
91105
sortable: true,
92106
truncateText: true,
93107
},
94108
{
95-
field: MEMORY_FIELD,
96-
name: 'Memory',
97-
render: (memory: number) =>
98-
typeof memory !== 'undefined' ? `${memory} B` : `${METRIC_DEFAULT_MSG}`,
109+
field: MEASUREMENTS_FIELD,
110+
name: MEMORY_USAGE,
111+
render: (measurements: { memory?: { number?: number } }) => {
112+
const memoryValue = measurements?.memory?.number;
113+
return memoryValue !== undefined ? `${memoryValue} B` : METRIC_DEFAULT_MSG;
114+
},
99115
sortable: true,
100116
truncateText: true,
101117
},
102118
{
103119
field: INDICES_FIELD,
104-
name: 'Indices',
120+
name: INDICES,
105121
render: (indices: string[]) => Array.from(new Set(indices.flat())).join(', '),
106122
sortable: true,
107123
truncateText: true,
108124
},
109125
{
110126
field: SEARCH_TYPE_FIELD,
111-
name: 'Search type',
127+
name: SEARCH_TYPE,
112128
render: (searchType: string) => searchType.replaceAll('_', ' '),
113129
sortable: true,
114130
truncateText: true,
115131
},
116132
{
117133
field: NODE_ID_FIELD,
118-
name: 'Coordinator node ID',
134+
name: NODE_ID,
119135
sortable: true,
120136
truncateText: true,
121137
},
122138
{
123139
field: TOTAL_SHARDS_FIELD,
124-
name: 'Total shards',
140+
name: TOTAL_SHARDS,
125141
sortable: true,
126142
truncateText: true,
127143
},
@@ -158,7 +174,7 @@ const QueryInsights = ({
158174
{
159175
type: 'field_value_selection',
160176
field: INDICES_FIELD,
161-
name: 'Indices',
177+
name: INDICES,
162178
multiSelect: true,
163179
options: filterDuplicates(
164180
queries.map((query) => {
@@ -174,7 +190,7 @@ const QueryInsights = ({
174190
{
175191
type: 'field_value_selection',
176192
field: SEARCH_TYPE_FIELD,
177-
name: 'Search type',
193+
name: SEARCH_TYPE,
178194
multiSelect: false,
179195
options: filterDuplicates(
180196
queries.map((query) => ({
@@ -187,7 +203,7 @@ const QueryInsights = ({
187203
{
188204
type: 'field_value_selection',
189205
field: NODE_ID_FIELD,
190-
name: 'Coordinator node ID',
206+
name: NODE_ID,
191207
multiSelect: true,
192208
options: filterDuplicates(
193209
queries.map((query) => ({
@@ -212,9 +228,7 @@ const QueryInsights = ({
212228
executeQueryOptions={{
213229
defaultFields: [
214230
TIMESTAMP_FIELD,
215-
LATENCY_FIELD,
216-
CPU_FIELD,
217-
MEMORY_FIELD,
231+
MEASUREMENTS_FIELD,
218232
INDICES_FIELD,
219233
SEARCH_TYPE_FIELD,
220234
NODE_ID_FIELD,

Diff for: public/pages/TopNQueries/TopNQueries.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { CoreStart } from 'opensearch-dashboards/public';
1111
import QueryInsights from '../QueryInsights/QueryInsights';
1212
import Configuration from '../Configuration/Configuration';
1313
import QueryDetails from '../QueryDetails/QueryDetails';
14+
import { SearchQueryRecord } from '../../../types/types';
1415

1516
export const QUERY_INSIGHTS = '/queryInsights';
1617
export const CONFIGURATION = '/configuration';
@@ -66,7 +67,7 @@ const TopNQueries = ({ core }: { core: CoreStart }) => {
6667
}
6768
};
6869

69-
const [queries, setQueries] = useState<any[]>([]);
70+
const [queries, setQueries] = useState<SearchQueryRecord[]>([]);
7071

7172
const tabs: Array<{ id: string; name: string; route: string }> = [
7273
{
@@ -114,7 +115,11 @@ const TopNQueries = ({ core }: { core: CoreStart }) => {
114115
};
115116
const fetchMetric = async (endpoint: string) => {
116117
try {
117-
const response = await core.http.get(endpoint, params);
118+
// TODO: #13 refactor the interface definitions for requests and responses
119+
const response: { response: { top_queries: SearchQueryRecord[] } } = await core.http.get(
120+
endpoint,
121+
params
122+
);
118123
return {
119124
response: {
120125
top_queries: Array.isArray(response?.response?.top_queries)
@@ -142,7 +147,7 @@ const TopNQueries = ({ core }: { core: CoreStart }) => {
142147
...respCpu.response.top_queries,
143148
...respMemory.response.top_queries,
144149
];
145-
const noDuplicates = Array.from(
150+
const noDuplicates: SearchQueryRecord[] = Array.from(
146151
new Set(newQueries.map((item) => JSON.stringify(item)))
147152
).map((item) => JSON.parse(item));
148153
setQueries(noDuplicates);

0 commit comments

Comments
 (0)