Skip to content

Commit 8ee8678

Browse files
authored
New Query Enhancement UI (#7309) (#7457)
* UI changes * update snapshots * styling * correct license * more cleanup * more styling and update snapshots --------- Signed-off-by: abbyhu2000 <abigailhu2000@gmail.com>
1 parent a53186b commit 8ee8678

13 files changed

+1502
-93
lines changed

changelogs/fragments/7309.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
feat:
2+
- Update query enhancement UI ([#7309](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7309))

src/plugins/data/public/ui/query_editor/__snapshots__/language_selector.test.tsx.snap

+1,103
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/data/public/ui/query_editor/_language_selector.scss

+21-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
.languageSelector {
6-
min-width: 140px;
7-
border-bottom: $euiBorderThin !important;
6+
height: 100%;
7+
8+
.languageSelector__button {
9+
&:hover {
10+
text-decoration: none; // Prevents text underline on hover
11+
}
12+
}
13+
14+
* {
15+
font-size: small;
16+
}
17+
}
18+
19+
.languageSelector__menuItem {
20+
padding-left: 2px;
21+
padding-right: 2px;
22+
align-items: center;
23+
24+
&:hover {
25+
text-decoration: none; // Prevents text underline on hover
26+
}
827
}

src/plugins/data/public/ui/query_editor/_query_editor.scss

+38-5
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,32 @@
1515
// overflow: auto;
1616
}
1717

18-
.osdQueryEditor__languageWrapper {
19-
:first-child {
20-
box-shadow: none !important;
21-
height: 100%;
22-
border-radius: 0;
18+
.osdQueryEditorFooter-isHidden {
19+
display: none;
20+
}
21+
22+
.osdQueryEditorFooter {
23+
color: $euiTextSubduedColor; // Apply the subdued color to all text in this class
24+
height: 25px;
25+
26+
* {
27+
color: inherit;
28+
font-size: $euiFontSizeXS;
29+
align-items: center;
2330
}
2431
}
2532

33+
.osdQueryEditor__collapseWrapper {
34+
box-shadow: $euiTextSubduedColor;
35+
}
36+
37+
.osdQueryEditor__languageWrapper {
38+
align-items: center;
39+
justify-content: center;
40+
max-height: 40px;
41+
border: $euiBorderThin;
42+
}
43+
2644
.osdQueryEditor__dataSourceWrapper {
2745
.dataSourceSelect {
2846
border-bottom: $euiBorderThin !important;
@@ -42,6 +60,7 @@
4260
.osdQueryEditor__dataSetWrapper {
4361
.dataExplorerDSSelect {
4462
border-bottom: $euiBorderThin !important;
63+
max-width: 375px;
4564

4665
div:is([class$="--group"]) {
4766
padding: 0 !important;
@@ -53,6 +72,20 @@
5372
}
5473
}
5574

75+
.osdQueryEditor__prependWrapper {
76+
box-shadow: $euiTextSubduedColor;
77+
}
78+
79+
.osdQueryEditor__prependWrapper-isCollapsed {
80+
box-shadow: none;
81+
}
82+
83+
.osdQueryEditor--updateButtonWrapper {
84+
:first-child {
85+
min-width: 0 !important;
86+
}
87+
}
88+
5689
@include euiBreakpoint("xs", "s") {
5790
.osdQueryEditor--withDatePicker {
5891
> :first-child {

src/plugins/data/public/ui/query_editor/language_selector.test.tsx

+2-16
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,7 @@ describe('LanguageSelector', () => {
5353
},
5454
})
5555
);
56-
const euiComboBox = component.find(EuiCompressedComboBox);
57-
expect(euiComboBox.prop('selectedOptions')).toEqual(
58-
expect.arrayContaining([
59-
{
60-
label: 'Lucene',
61-
},
62-
])
63-
);
56+
expect(component).toMatchSnapshot();
6457
});
6558

6659
it('should select DQL if language is kuery', () => {
@@ -72,13 +65,6 @@ describe('LanguageSelector', () => {
7265
},
7366
})
7467
);
75-
const euiComboBox = component.find(EuiCompressedComboBox);
76-
expect(euiComboBox.prop('selectedOptions')).toEqual(
77-
expect.arrayContaining([
78-
{
79-
label: 'DQL',
80-
},
81-
])
82-
);
68+
expect(component).toMatchSnapshot();
8369
});
8470
});

src/plugins/data/public/ui/query_editor/language_selector.tsx

+62-20
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
*/
55

66
import {
7-
EuiCompressedComboBox,
8-
EuiComboBoxOptionOption,
97
PopoverAnchorPosition,
8+
EuiContextMenuPanel,
9+
EuiPopover,
10+
EuiButtonEmpty,
11+
EuiContextMenuItem,
1012
} from '@elastic/eui';
1113
import { i18n } from '@osd/i18n';
12-
import React from 'react';
14+
import React, { useState } from 'react';
1315
import { getUiService } from '../../services';
1416

15-
interface Props {
17+
export interface QueryLanguageSelectorProps {
1618
language: string;
1719
onSelectLanguage: (newLanguage: string) => void;
1820
anchorPosition?: PopoverAnchorPosition;
1921
appName?: string;
22+
isFooter?: boolean;
2023
}
2124

2225
const mapExternalLanguageToOptions = (language: string) => {
@@ -26,15 +29,21 @@ const mapExternalLanguageToOptions = (language: string) => {
2629
};
2730
};
2831

29-
export const QueryLanguageSelector = (props: Props) => {
32+
export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => {
33+
const [isPopoverOpen, setPopover] = useState(false);
34+
35+
const onButtonClick = () => {
36+
setPopover(!isPopoverOpen);
37+
};
38+
3039
const dqlLabel = i18n.translate('data.query.queryEditor.dqlLanguageName', {
3140
defaultMessage: 'DQL',
3241
});
3342
const luceneLabel = i18n.translate('data.query.queryEditor.luceneLanguageName', {
3443
defaultMessage: 'Lucene',
3544
});
3645

37-
const languageOptions: EuiComboBoxOptionOption[] = [
46+
const languageOptions = [
3847
{
3948
label: dqlLabel,
4049
value: 'kuery',
@@ -68,25 +77,58 @@ export const QueryLanguageSelector = (props: Props) => {
6877
)?.label as string) ?? languageOptions[0].label,
6978
};
7079

71-
const handleLanguageChange = (newLanguage: EuiComboBoxOptionOption[]) => {
72-
const queryLanguage = newLanguage[0].value as string;
73-
props.onSelectLanguage(queryLanguage);
74-
uiService.Settings.setUserQueryLanguage(queryLanguage);
80+
const handleLanguageChange = (newLanguage: string) => {
81+
props.onSelectLanguage(newLanguage);
82+
uiService.Settings.setUserQueryLanguage(newLanguage);
7583
};
7684

7785
uiService.Settings.setUserQueryLanguage(props.language);
7886

87+
const languageOptionsMenu = languageOptions.map((language) => {
88+
return (
89+
<EuiContextMenuItem
90+
key={language.label}
91+
className="languageSelector__menuItem"
92+
icon={language.label === selectedLanguage.label ? 'check' : 'empty'}
93+
onClick={() => {
94+
setPopover(false);
95+
handleLanguageChange(language.value);
96+
}}
97+
>
98+
{language.label}
99+
</EuiContextMenuItem>
100+
);
101+
});
79102
return (
80-
<EuiCompressedComboBox
81-
fullWidth
103+
<EuiPopover
82104
className="languageSelector"
83-
data-test-subj="languageSelector"
84-
options={languageOptions}
85-
selectedOptions={[selectedLanguage]}
86-
onChange={handleLanguageChange}
87-
singleSelection={{ asPlainText: true }}
88-
isClearable={false}
89-
async
90-
/>
105+
button={
106+
<EuiButtonEmpty
107+
iconSide="right"
108+
iconSize="s"
109+
onClick={onButtonClick}
110+
className="languageSelector__button"
111+
iconType={props.isFooter ? 'arrowDown' : undefined}
112+
>
113+
{selectedLanguage.label}
114+
</EuiButtonEmpty>
115+
}
116+
isOpen={isPopoverOpen}
117+
closePopover={() => setPopover(false)}
118+
panelPaddingSize="none"
119+
anchorPosition={props.anchorPosition ?? 'downLeft'}
120+
>
121+
<EuiContextMenuPanel
122+
initialFocusedItemIndex={languageOptions.findIndex(
123+
(option) => option.label === selectedLanguage.label
124+
)}
125+
size="s"
126+
items={languageOptionsMenu}
127+
/>
128+
</EuiPopover>
91129
);
92130
};
131+
132+
// Needed for React.lazy
133+
// eslint-disable-next-line import/no-default-export
134+
export default QueryLanguageSelector;

0 commit comments

Comments
 (0)