diff --git a/.github/workflows/cypress_workflow.yml b/.github/workflows/cypress_workflow.yml index 669f596df898..b404f9c46240 100644 --- a/.github/workflows/cypress_workflow.yml +++ b/.github/workflows/cypress_workflow.yml @@ -32,7 +32,7 @@ env: TEST_REPO: ${{ inputs.test_repo != '' && inputs.test_repo || 'opensearch-project/opensearch-dashboards-functional-test' }} TEST_BRANCH: "${{ inputs.test_branch != '' && inputs.test_branch || github.base_ref }}" FTR_PATH: 'ftr' - START_CMD: 'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true --csp.warnLegacyBrowsers=false' + START_CMD: 'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --savedObjects.maxImportPayloadBytes=10485760 --server.maxPayloadBytes=1759977 --logging.json=false --data.search.aggs.shardDelay.enabled=true --csp.warnLegacyBrowsers=false --uiSettings.overrides["query:enhancements:enabled"]=false' OPENSEARCH_SNAPSHOT_CMD: 'node ../scripts/opensearch snapshot -E cluster.routing.allocation.disk.threshold_enabled=false' CYPRESS_BROWSER: 'chromium' CYPRESS_VISBUILDER_ENABLED: true diff --git a/changelogs/fragments/6478.yml b/changelogs/fragments/6478.yml new file mode 100644 index 000000000000..d8009500a060 --- /dev/null +++ b/changelogs/fragments/6478.yml @@ -0,0 +1,2 @@ +feat: +- [Workspace] Duplicate selected/all saved objects ([#6478](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6478)) \ No newline at end of file diff --git a/changelogs/fragments/7157.yml b/changelogs/fragments/7157.yml new file mode 100644 index 000000000000..e7b25524e961 --- /dev/null +++ b/changelogs/fragments/7157.yml @@ -0,0 +1,2 @@ +feat: +- Query editor and dataframes datasources container ([#7157](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7157)) \ No newline at end of file diff --git a/changelogs/fragments/7183.yml b/changelogs/fragments/7183.yml new file mode 100644 index 000000000000..f3fc5235226d --- /dev/null +++ b/changelogs/fragments/7183.yml @@ -0,0 +1,2 @@ +feat: +- [QueryEditorExtensions] change `isEnabled` to an observable ([#7183](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7183)) \ No newline at end of file diff --git a/changelogs/fragments/7291.yml b/changelogs/fragments/7291.yml new file mode 100644 index 000000000000..8d1d6b4f8a63 --- /dev/null +++ b/changelogs/fragments/7291.yml @@ -0,0 +1,2 @@ +deprecate: +- Remove data enhancements config and readonly flag. Removes dead url link, ([#7291](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7291)) \ No newline at end of file diff --git a/changelogs/fragments/7309.yml b/changelogs/fragments/7309.yml new file mode 100644 index 000000000000..0925eb170794 --- /dev/null +++ b/changelogs/fragments/7309.yml @@ -0,0 +1,2 @@ +feat: +- Update query enhancement UI ([#7309](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7309)) \ No newline at end of file diff --git a/changelogs/fragments/7314.yml b/changelogs/fragments/7314.yml new file mode 100644 index 000000000000..a3ff4b409d54 --- /dev/null +++ b/changelogs/fragments/7314.yml @@ -0,0 +1,2 @@ +fix: +- Unused config setting and remove data sources as a required plugin. ([#7314](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7314)) \ No newline at end of file diff --git a/changelogs/fragments/7329.yml b/changelogs/fragments/7329.yml new file mode 100644 index 000000000000..e30e73df5936 --- /dev/null +++ b/changelogs/fragments/7329.yml @@ -0,0 +1,2 @@ +feat: +- Use compressed DataSourceSelector ([#7329](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7329)) diff --git a/config/opensearch_dashboards.yml b/config/opensearch_dashboards.yml index bc46a1bdd2b0..969fec9e8fa9 100644 --- a/config/opensearch_dashboards.yml +++ b/config/opensearch_dashboards.yml @@ -359,9 +359,6 @@ # This publishes the Application Usage and UI Metrics into the saved object, which can be accessed by /api/stats?extended=true&legacy=true&exclude_usage=false # usageCollection.uiMetric.enabled: false -# Set the value to true to enable enhancements for the data plugin -# data.enhancements.enabled: false - # Set the backend roles in groups or users, whoever has the backend roles or exactly match the user ids defined in this config will be regard as dashboard admin. # Dashboard admin will have the access to all the workspaces(workspace.enabled: true) and objects inside OpenSearch Dashboards. # opensearchDashboards.dashboardAdmin.groups: ["dashboard_admin"] diff --git a/package.json b/package.json index 1de337527a91..b24c09ea6a67 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "start": "scripts/use_node scripts/opensearch_dashboards --dev", "start:docker": "scripts/use_node scripts/opensearch_dashboards --dev --opensearch.hosts=$OPENSEARCH_HOSTS --opensearch.ignoreVersionMismatch=true --server.host=$SERVER_HOST", "start:security": "scripts/use_node scripts/opensearch_dashboards --dev --security", - "start:enhancements": "scripts/use_node scripts/opensearch_dashboards --dev --data.enhancements.enabled=true --data_source.enabled=true --uiSettings.overrides['query:enhancements:enabled']=true --uiSettings.overrides['query:dataSource:readOnly']=false", + "start:enhancements": "scripts/use_node scripts/opensearch_dashboards --dev --uiSettings.overrides['query:enhancements:enabled']=true", "debug": "scripts/use_node --nolazy --inspect scripts/opensearch_dashboards --dev", "debug-break": "scripts/use_node --nolazy --inspect-brk scripts/opensearch_dashboards --dev", "lint": "yarn run lint:es && yarn run lint:style", @@ -140,7 +140,7 @@ "dependencies": { "@aws-crypto/client-node": "^3.1.1", "@elastic/datemath": "5.0.3", - "@elastic/eui": "npm:@opensearch-project/oui@1.5.1", + "@elastic/eui": "npm:@opensearch-project/oui@1.7.0", "@elastic/good": "^9.0.1-kibana3", "@elastic/numeral": "npm:@amoo-miki/numeral@2.6.0", "@elastic/request-crypto": "2.0.0", diff --git a/packages/osd-plugin-generator/template/public/components/app.tsx.ejs b/packages/osd-plugin-generator/template/public/components/app.tsx.ejs index 876b3f8c5e75..2029a69dd8db 100644 --- a/packages/osd-plugin-generator/template/public/components/app.tsx.ejs +++ b/packages/osd-plugin-generator/template/public/components/app.tsx.ejs @@ -4,7 +4,7 @@ import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; import { BrowserRouter as Router } from 'react-router-dom'; import { -EuiButton, +EuiSmallButton, EuiHorizontalRule, EuiPage, EuiPageBody, diff --git a/packages/osd-ui-framework/package.json b/packages/osd-ui-framework/package.json index 68b2950369dd..860a50d39c49 100644 --- a/packages/osd-ui-framework/package.json +++ b/packages/osd-ui-framework/package.json @@ -23,7 +23,7 @@ "enzyme-adapter-react-16": "^1.9.1" }, "devDependencies": { - "@elastic/eui": "npm:@opensearch-project/oui@1.5.1", + "@elastic/eui": "npm:@opensearch-project/oui@1.7.0", "@osd/babel-preset": "1.0.0", "@osd/optimizer": "1.0.0", "comment-stripper": "^0.0.4", diff --git a/packages/osd-ui-shared-deps/package.json b/packages/osd-ui-shared-deps/package.json index bc1a256a9bc9..1d4092f7df5e 100644 --- a/packages/osd-ui-shared-deps/package.json +++ b/packages/osd-ui-shared-deps/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@elastic/charts": "31.1.0", - "@elastic/eui": "npm:@opensearch-project/oui@1.5.1", + "@elastic/eui": "npm:@opensearch-project/oui@1.7.0", "@elastic/numeral": "npm:@amoo-miki/numeral@2.6.0", "@opensearch/datemath": "5.0.3", "@osd/i18n": "1.0.0", diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap index 2165a2112f24..5fd679baf7e3 100644 --- a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap +++ b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap @@ -18,7 +18,7 @@ exports[`FatalErrorsScreen rendering render matches snapshot 1`] = ` - , - , + @@ -39,7 +39,7 @@ exports[`FatalErrorsScreen rendering render matches snapshot 1`] = ` id="core.fatalErrors.goBackButtonLabel" values={Object {}} /> - , + , ] } body={ diff --git a/src/core/public/fatal_errors/fatal_errors_screen.tsx b/src/core/public/fatal_errors/fatal_errors_screen.tsx index ecb95f3217e3..2333bf006813 100644 --- a/src/core/public/fatal_errors/fatal_errors_screen.tsx +++ b/src/core/public/fatal_errors/fatal_errors_screen.tsx @@ -29,8 +29,8 @@ */ import { - EuiButton, - EuiButtonEmpty, + EuiSmallButton, + EuiSmallButtonEmpty, EuiCallOut, EuiCodeBlock, EuiEmptyPrompt, @@ -125,7 +125,7 @@ export class FatalErrorsScreen extends React.Component { } actions={[ - { id="core.fatalErrors.clearYourSessionButtonLabel" defaultMessage="Clear your session" /> - , - + , + - , + , ]} /> {this.state.errors.map((error, i) => ( diff --git a/src/core/public/notifications/toasts/error_toast.tsx b/src/core/public/notifications/toasts/error_toast.tsx index 4f4debbb28c6..5924543b8eb5 100644 --- a/src/core/public/notifications/toasts/error_toast.tsx +++ b/src/core/public/notifications/toasts/error_toast.tsx @@ -32,6 +32,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { + EuiSmallButton, EuiButton, EuiCallOut, EuiCodeBlock, @@ -107,12 +108,12 @@ function showErrorDialog({ )} - modal.close()} fill> + modal.close()} fill> - + diff --git a/src/core/server/rendering/views/template.tsx b/src/core/server/rendering/views/template.tsx index 8aa7903d8df1..7ed7c316ecbc 100644 --- a/src/core/server/rendering/views/template.tsx +++ b/src/core/server/rendering/views/template.tsx @@ -67,8 +67,6 @@ export const Template: FunctionComponent = ({ * ToDo: Custom branded favicons will not work correctly across all browsers with * these `link` elements and single type. Try to guess the image and use only one. * - * Favicons (generated from https://realfavicongenerator.net/) - * * For user customized favicon using yml file: * If user inputs a valid URL, we guarantee basic favicon customization, such as * browser favicon(Chrome, Firefox, Safari, and Edge), apple touch icon, safari diff --git a/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap b/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap index 9ab66e07807d..0e08b53cc28d 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap +++ b/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap @@ -28,10 +28,10 @@ exports[`Field for array setting should render as read only if saving is disable } > - - - + `; @@ -101,10 +101,10 @@ exports[`Field for array setting should render as read only with help text if ov } > - - - + `; @@ -173,10 +173,10 @@ exports[`Field for array setting should render custom setting icon if it is cust } > - - - + `; @@ -224,10 +224,10 @@ exports[`Field for array setting should render default value if there is no user } > - - - + `; @@ -292,10 +292,10 @@ exports[`Field for array setting should render unsaved value if there are unsave } > - - - + `; @@ -377,10 +377,10 @@ exports[`Field for array setting should render user value if there is user value } > - - - + `; @@ -445,10 +445,10 @@ exports[`Field for boolean setting should render as read only if saving is disab } > - - - + `; @@ -524,10 +524,10 @@ exports[`Field for boolean setting should render as read only with help text if } > - - - + `; @@ -602,10 +602,10 @@ exports[`Field for boolean setting should render custom setting icon if it is cu } > - - - + `; @@ -659,10 +659,10 @@ exports[`Field for boolean setting should render default value if there is no us } > - - - + `; @@ -733,10 +733,10 @@ exports[`Field for boolean setting should render unsaved value if there are unsa } > - - - + `; @@ -820,10 +820,10 @@ exports[`Field for boolean setting should render user value if there is user val } > - - - + `; @@ -894,10 +894,10 @@ exports[`Field for image setting should render as read only if saving is disable } > - - - + `; @@ -970,10 +970,10 @@ exports[`Field for image setting should render as read only with help text if ov } > - - + `; @@ -1040,10 +1040,10 @@ exports[`Field for image setting should render custom setting icon if it is cust } > - - - + `; @@ -1094,10 +1094,10 @@ exports[`Field for image setting should render default value if there is no user } > - - - + `; @@ -1165,10 +1165,10 @@ exports[`Field for image setting should render unsaved value if there are unsave } > - - - + `; @@ -1248,10 +1248,10 @@ exports[`Field for image setting should render user value if there is user value } > - - + `; @@ -1352,10 +1352,10 @@ exports[`Field for json setting should render as read only if saving is disabled } > - - + `; @@ -1448,10 +1448,10 @@ exports[`Field for json setting should render as read only with help text if ove } > - - + `; @@ -1540,10 +1540,10 @@ exports[`Field for json setting should render custom setting icon if it is custo } > - - + `; @@ -1636,10 +1636,10 @@ exports[`Field for json setting should render default value if there is no user } > - - + `; @@ -1741,10 +1741,10 @@ exports[`Field for json setting should render unsaved value if there are unsaved } > - - + `; @@ -1849,10 +1849,10 @@ exports[`Field for json setting should render user value if there is user value } > - - + `; @@ -1937,10 +1937,10 @@ exports[`Field for markdown setting should render as read only if saving is disa } > - - + `; @@ -2030,10 +2030,10 @@ exports[`Field for markdown setting should render as read only with help text if } > - - + `; @@ -2122,10 +2122,10 @@ exports[`Field for markdown setting should render custom setting icon if it is c } > - - + `; @@ -2193,10 +2193,10 @@ exports[`Field for markdown setting should render default value if there is no u } > - - + `; @@ -2281,10 +2281,10 @@ exports[`Field for markdown setting should render unsaved value if there are uns } > - - + `; @@ -2382,10 +2382,10 @@ exports[`Field for markdown setting should render user value if there is user va } > - - + `; @@ -2470,10 +2470,10 @@ exports[`Field for number setting should render as read only if saving is disabl } > - - - + `; @@ -2543,10 +2543,10 @@ exports[`Field for number setting should render as read only with help text if o } > - - - + `; @@ -2615,10 +2615,10 @@ exports[`Field for number setting should render custom setting icon if it is cus } > - - - + `; @@ -2666,10 +2666,10 @@ exports[`Field for number setting should render default value if there is no use } > - - - + `; @@ -2734,10 +2734,10 @@ exports[`Field for number setting should render unsaved value if there are unsav } > - - - + `; @@ -2815,10 +2815,10 @@ exports[`Field for number setting should render user value if there is user valu } > - - - + `; @@ -2883,10 +2883,10 @@ exports[`Field for select setting should render as read only if saving is disabl } > - - - + `; @@ -2972,10 +2972,10 @@ exports[`Field for select setting should render as read only with help text if o } > - - - + `; @@ -3060,10 +3060,10 @@ exports[`Field for select setting should render custom setting icon if it is cus } > - - - + `; @@ -3127,10 +3127,10 @@ exports[`Field for select setting should render default value if there is no use } > - - - + `; @@ -3211,10 +3211,10 @@ exports[`Field for select setting should render unsaved value if there are unsav } > - - - + `; @@ -3308,10 +3308,10 @@ exports[`Field for select setting should render user value if there is user valu } > - - - + `; @@ -3392,10 +3392,10 @@ exports[`Field for string setting should render as read only if saving is disabl } > - - - + `; @@ -3465,10 +3465,10 @@ exports[`Field for string setting should render as read only with help text if o } > - - - + `; @@ -3537,10 +3537,10 @@ exports[`Field for string setting should render custom setting icon if it is cus } > - - - + `; @@ -3588,10 +3588,10 @@ exports[`Field for string setting should render default value if there is no use } > - - - + `; @@ -3656,10 +3656,10 @@ exports[`Field for string setting should render unsaved value if there are unsav } > - - - + `; @@ -3737,10 +3737,10 @@ exports[`Field for string setting should render user value if there is user valu } > - - - + `; @@ -3805,10 +3805,10 @@ exports[`Field for stringWithValidation setting should render as read only if sa } > - - - + `; @@ -3878,10 +3878,10 @@ exports[`Field for stringWithValidation setting should render as read only with } > - - - + `; @@ -3950,10 +3950,10 @@ exports[`Field for stringWithValidation setting should render custom setting ico } > - - - + `; @@ -4001,10 +4001,10 @@ exports[`Field for stringWithValidation setting should render default value if t } > - - - + `; @@ -4069,10 +4069,10 @@ exports[`Field for stringWithValidation setting should render unsaved value if t } > - - - + `; @@ -4150,10 +4150,10 @@ exports[`Field for stringWithValidation setting should render user value if ther } > - - - + `; diff --git a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx index c21c81cafa28..75dd18fffde4 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx @@ -42,17 +42,17 @@ import { EuiScreenReaderOnly, EuiCodeEditor, EuiDescribedFormGroup, - EuiFieldNumber, - EuiFieldText, - EuiFilePicker, - EuiFormRow, + EuiCompressedFieldNumber, + EuiCompressedFieldText, + EuiCompressedFilePicker, + EuiCompressedFormRow, EuiIconTip, EuiImage, EuiLink, EuiSpacer, EuiText, - EuiSelect, - EuiSwitch, + EuiCompressedSelect, + EuiCompressedSwitch, EuiSwitchEvent, EuiToolTip, } from '@elastic/eui'; @@ -100,7 +100,7 @@ export const getEditableValue = ( }; export class Field extends PureComponent { - private changeImageForm = React.createRef(); + private changeImageForm = React.createRef(); getDisplayedDefaultValue( type: UiSettingsType, @@ -326,7 +326,7 @@ export class Field extends PureComponent { switch (type) { case 'boolean': return ( - @@ -373,7 +373,7 @@ export class Field extends PureComponent { return ; } else { return ( - { } case 'select': return ( - { @@ -404,7 +404,7 @@ export class Field extends PureComponent { ); case 'number': return ( - { ); default: return ( - { description={this.renderDescription(setting)} fullWidth > - { )} - + ); } diff --git a/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap index bac6be2733fd..04bb8ddcff99 100644 --- a/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap +++ b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap @@ -61,9 +61,9 @@ exports[`ImportFlyout Component renders correctly 1`] = `
-
-
- +
- - +
- -
- -
+
+ -
- -
-
- -
+
+ +
+ + -
- -
-
-
- + +
+ +
+
+
+ +
- +
diff --git a/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap index 343c6b351229..29e14c2c986d 100644 --- a/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap +++ b/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap @@ -14,7 +14,7 @@ exports[`ImportModeControl Component should render correclty 1`] = ` } } > - { return ( - { /> } > - { onChange={setImportFile} data-test-subj="queryFilePicker" /> - - +
+ setImportMode(newValues)} /> -
+ ); }; diff --git a/src/plugins/console/public/application/components/import_mode_control.test.tsx b/src/plugins/console/public/application/components/import_mode_control.test.tsx index 219cc2f1c5fc..32ab6322d7eb 100644 --- a/src/plugins/console/public/application/components/import_mode_control.test.tsx +++ b/src/plugins/console/public/application/components/import_mode_control.test.tsx @@ -10,7 +10,7 @@ import { nextTick, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { ImportModeControl } from './import_mode_control'; import { EuiFormLegendProps, EuiRadioGroupProps } from '@elastic/eui'; -const radioGroupIdentifier = 'EuiRadioGroup'; +const radioGroupIdentifier = 'EuiCompressedRadioGroup'; describe('ImportModeControl Component', () => { let component: ShallowWrapper, React.Component<{}, {}, any>>; diff --git a/src/plugins/console/public/application/components/import_mode_control.tsx b/src/plugins/console/public/application/components/import_mode_control.tsx index 0b543a9c593c..603a37f51fa9 100644 --- a/src/plugins/console/public/application/components/import_mode_control.tsx +++ b/src/plugins/console/public/application/components/import_mode_control.tsx @@ -4,7 +4,7 @@ */ import React, { useState } from 'react'; -import { EuiFormFieldset, EuiTitle, EuiRadioGroup } from '@elastic/eui'; +import { EuiFormFieldset, EuiTitle, EuiCompressedRadioGroup } from '@elastic/eui'; import { i18n } from '@osd/i18n'; export interface ImportModeControlProps { @@ -43,7 +43,7 @@ export const ImportModeControl = ({ initialValues, updateSelection }: ImportMode }; const overwriteRadio = ( - onChange({ overwrite: id === overwriteEnabled.id })} diff --git a/src/plugins/console/public/application/components/settings_modal.tsx b/src/plugins/console/public/application/components/settings_modal.tsx index 15405a7e6c7e..d97b7c72a03f 100644 --- a/src/plugins/console/public/application/components/settings_modal.tsx +++ b/src/plugins/console/public/application/components/settings_modal.tsx @@ -34,17 +34,17 @@ import { i18n } from '@osd/i18n'; import { FormattedMessage } from '@osd/i18n/react'; import { - EuiButton, - EuiButtonEmpty, - EuiFieldNumber, - EuiFormRow, - EuiCheckboxGroup, + EuiSmallButton, + EuiSmallButtonEmpty, + EuiCompressedFieldNumber, + EuiCompressedFormRow, + EuiCompressedCheckboxGroup, EuiModal, EuiModalBody, EuiModalFooter, EuiModalHeader, EuiModalHeaderTitle, - EuiSwitch, + EuiCompressedSwitch, } from '@elastic/eui'; import { DevToolsSettings } from '../../services'; @@ -122,7 +122,7 @@ export function DevToolsSettingsModal(props: Props) { const pollingFields = fields || indices || templates ? ( - } > - setPolling(e.target.checked)} /> - + - { @@ -167,7 +167,7 @@ export function DevToolsSettingsModal(props: Props) { defaultMessage="Refresh autocomplete suggestions" id="console.settingsPage.refreshButtonLabel" /> - + ) : undefined; @@ -184,12 +184,12 @@ export function DevToolsSettingsModal(props: Props) { - } > - - + - - + setWrapMode(e.target.checked)} /> - + - } > - setTripleQuotes(e.target.checked)} /> - + - } > - { const { stateSetter, ...rest } = opts; return rest; @@ -259,19 +259,19 @@ export function DevToolsSettingsModal(props: Props) { onAutocompleteChange(e as AutocompleteOptions); }} /> - + {pollingFields} - + - + - + - + ); diff --git a/src/plugins/console/public/application/components/something_went_wrong_callout.tsx b/src/plugins/console/public/application/components/something_went_wrong_callout.tsx index f12d5b9cda88..b868164e5c8e 100644 --- a/src/plugins/console/public/application/components/something_went_wrong_callout.tsx +++ b/src/plugins/console/public/application/components/something_went_wrong_callout.tsx @@ -31,7 +31,7 @@ import React, { FunctionComponent, useEffect } from 'react'; import { FormattedMessage } from '@osd/i18n/react'; import { i18n } from '@osd/i18n'; -import { EuiCallOut, EuiText, EuiButton, EuiSpacer } from '@elastic/eui'; +import { EuiCallOut, EuiText, EuiSmallButton, EuiSpacer } from '@elastic/eui'; interface Props { error: Error; @@ -61,9 +61,9 @@ export const SomethingWentWrongCallout: FunctionComponent = ({ error, onB

- onButtonClick()}> + onButtonClick()}> - + ); }; diff --git a/src/plugins/console/public/application/components/welcome_panel.tsx b/src/plugins/console/public/application/components/welcome_panel.tsx index bc30539e57c1..ba9e499b03bb 100644 --- a/src/plugins/console/public/application/components/welcome_panel.tsx +++ b/src/plugins/console/public/application/components/welcome_panel.tsx @@ -37,7 +37,7 @@ import { EuiFlyoutHeader, EuiFlyoutBody, EuiTitle, - EuiButton, + EuiSmallButton, EuiText, EuiFlyoutFooter, } from '@elastic/eui'; @@ -131,14 +131,14 @@ export function WelcomePanel(props: Props) { - - + ); diff --git a/src/plugins/console/public/application/containers/console_history/console_history.tsx b/src/plugins/console/public/application/containers/console_history/console_history.tsx index 08704c442bbc..925224c53783 100644 --- a/src/plugins/console/public/application/containers/console_history/console_history.tsx +++ b/src/plugins/console/public/application/containers/console_history/console_history.tsx @@ -39,8 +39,8 @@ import { EuiTitle, EuiFlexItem, EuiFlexGroup, - EuiButtonEmpty, - EuiButton, + EuiSmallButtonEmpty, + EuiSmallButton, } from '@elastic/eui'; import { useServicesContext } from '../../contexts'; @@ -210,25 +210,25 @@ export function ConsoleHistory({ close }: Props) { - clear()}> + clear()}> {i18n.translate('console.historyPage.clearHistoryButtonLabel', { defaultMessage: 'Clear', })} - + - close()}> + close()}> {i18n.translate('console.historyPage.closehistoryButtonLabel', { defaultMessage: 'Close', })} - + - restoreRequestFromHistory(selectedReq.current)} @@ -236,7 +236,7 @@ export function ConsoleHistory({ close }: Props) { {i18n.translate('console.historyPage.applyHistoryButtonLabel', { defaultMessage: 'Apply', })} - + diff --git a/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/create_button.test.tsx.snap b/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/create_button.test.tsx.snap index 4512135a4927..1ca3fd80e890 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/create_button.test.tsx.snap +++ b/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/create_button.test.tsx.snap @@ -245,7 +245,7 @@ exports[`create button with props renders button dropdown menu when two provider - + } closePopover={[Function]} display="inlineBlock" @@ -274,79 +274,89 @@ exports[`create button with props renders button dropdown menu when two provider
- - - - - + + + + +
@@ -480,78 +490,87 @@ exports[`create button with props renders single button when one provider given diff --git a/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/dashboard_listing.test.tsx.snap b/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/dashboard_listing.test.tsx.snap index 1726e357eebf..678ddcaf5743 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/dashboard_listing.test.tsx.snap +++ b/src/plugins/dashboard/public/application/components/dashboard_listing/__snapshots__/dashboard_listing.test.tsx.snap @@ -2309,7 +2309,7 @@ exports[`dashboard listing render table listing with initial filters from URL 1` noItemsFragment={ - + } body={ @@ -3560,7 +3560,7 @@ exports[`dashboard listing renders call to action when no dashboards exist 1`] = noItemsFragment={ - + } body={ @@ -4811,7 +4811,7 @@ exports[`dashboard listing renders table rows 1`] = ` noItemsFragment={ - + } body={ @@ -6062,7 +6062,7 @@ exports[`dashboard listing renders warning when listingLimit is exceeded 1`] = ` noItemsFragment={ - + } body={ diff --git a/src/plugins/dashboard/public/application/components/dashboard_listing/create_button.tsx b/src/plugins/dashboard/public/application/components/dashboard_listing/create_button.tsx index 5baf945e3b5f..83f055b0ac39 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_listing/create_button.tsx +++ b/src/plugins/dashboard/public/application/components/dashboard_listing/create_button.tsx @@ -5,7 +5,7 @@ import React, { useState } from 'react'; import { FormattedMessage } from '@osd/i18n/react'; import { - EuiButton, + EuiSmallButton, EuiContextMenuItem, EuiContextMenuPanel, EuiFlexItem, @@ -47,7 +47,7 @@ const CreateButton = (props: CreateButtonProps) => { const renderCreateMenuDropDown = () => { const button = ( - { data-test-subj="createMenuDropdown" > - + ); return ( @@ -78,10 +78,15 @@ const CreateButton = (props: CreateButtonProps) => { const provider: DashboardProvider = Object.values(props.dashboardProviders!)[0]; return ( - +  {provider.createLinkText} - + ); }; diff --git a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/clone_modal.test.js.snap b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/clone_modal.test.js.snap index 1ea30b7fe0a6..559f69752b6e 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/clone_modal.test.js.snap +++ b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/clone_modal.test.js.snap @@ -34,7 +34,7 @@ exports[`renders DashboardCloneModal 1`] = `

- - @@ -53,8 +53,8 @@ exports[`renders DashboardCloneModal 1`] = ` id="dashboard.topNav.cloneModal.cancelButtonLabel" values={Object {}} /> - - + - + `; diff --git a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/save_modal.test.js.snap b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/save_modal.test.js.snap index bc4ed477d9ee..727dae147a96 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/save_modal.test.js.snap +++ b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/__snapshots__/save_modal.test.js.snap @@ -7,9 +7,9 @@ exports[`renders DashboardSaveModal 1`] = ` onSave={[Function]} options={ - - - - + - - + } showCopyOnSave={true} diff --git a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/clone_modal.tsx b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/clone_modal.tsx index fb1aefab7760..c4e2b2d32651 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/clone_modal.tsx +++ b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/clone_modal.tsx @@ -33,9 +33,9 @@ import { i18n } from '@osd/i18n'; import { FormattedMessage } from '@osd/i18n/react'; import { - EuiButton, - EuiButtonEmpty, - EuiFieldText, + EuiSmallButton, + EuiSmallButtonEmpty, + EuiCompressedFieldText, EuiModal, EuiModalBody, EuiModalFooter, @@ -191,7 +191,7 @@ export class DashboardCloneModal extends React.Component { - { - + - + - { id="dashboard.topNav.cloneModal.confirmButtonLabel" defaultMessage="Confirm Clone" /> - + ); diff --git a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/options.tsx b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/options.tsx index 2ea2c6f841f6..02534e06e62c 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/options.tsx +++ b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/options.tsx @@ -31,7 +31,7 @@ import React, { Component } from 'react'; import { i18n } from '@osd/i18n'; -import { EuiForm, EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { EuiForm, EuiCompressedFormRow, EuiCompressedSwitch } from '@elastic/eui'; interface Props { useMargins: boolean; @@ -70,8 +70,8 @@ export class OptionsMenu extends Component { render() { return ( - - + { onChange={this.handleUseMarginsChange} data-test-subj="dashboardMarginsCheckbox" /> - + - - + { onChange={this.handleHidePanelTitlesChange} data-test-subj="dashboardPanelTitlesCheckbox" /> - + ); } diff --git a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/save_modal.tsx b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/save_modal.tsx index f8e0fe674df8..3a8aa0538bba 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/save_modal.tsx +++ b/src/plugins/dashboard/public/application/components/dashboard_top_nav/top_nav/save_modal.tsx @@ -30,7 +30,7 @@ import React, { Fragment } from 'react'; import { FormattedMessage } from '@osd/i18n/react'; -import { EuiFormRow, EuiTextArea, EuiSwitch } from '@elastic/eui'; +import { EuiCompressedFormRow, EuiCompressedTextArea, EuiCompressedSwitch } from '@elastic/eui'; import { SavedObjectSaveModal } from '../../../../../../saved_objects/public'; @@ -110,7 +110,7 @@ export class DashboardSaveModal extends React.Component { renderDashboardSaveOptions() { return ( - { /> } > - - + - { /> } > - { /> } /> - + ); } diff --git a/src/plugins/dashboard/public/application/utils/get_nav_actions.tsx b/src/plugins/dashboard/public/application/utils/get_nav_actions.tsx index 205489739eab..32bfef083518 100644 --- a/src/plugins/dashboard/public/application/utils/get_nav_actions.tsx +++ b/src/plugins/dashboard/public/application/utils/get_nav_actions.tsx @@ -5,7 +5,7 @@ import React, { ReactElement, useState } from 'react'; import { i18n } from '@osd/i18n'; -import { EUI_MODAL_CANCEL_BUTTON, EuiCheckboxGroup } from '@elastic/eui'; +import { EUI_MODAL_CANCEL_BUTTON, EuiCompressedCheckboxGroup } from '@elastic/eui'; import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group'; import { SaveResult, @@ -265,7 +265,7 @@ export const getNavActions = ( }; return ( - } actions={ - - + } /> ); diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts index a00adb0b6290..863877322ad9 100644 --- a/src/plugins/data/common/constants.ts +++ b/src/plugins/data/common/constants.ts @@ -62,6 +62,5 @@ export const UI_SETTINGS = { FILTERS_EDITOR_SUGGEST_VALUES: 'filterEditor:suggestValues', QUERY_ENHANCEMENTS_ENABLED: 'query:enhancements:enabled', QUERY_DATAFRAME_HYDRATION_STRATEGY: 'query:dataframe:hydrationStrategy', - QUERY_DATA_SOURCE_READONLY: 'query:dataSource:readOnly', SEARCH_QUERY_LANGUAGE_BLOCKLIST: 'search:queryLanguageBlocklist', } as const; diff --git a/src/plugins/data/config.ts b/src/plugins/data/config.ts index 53252fb74b42..186691f3c917 100644 --- a/src/plugins/data/config.ts +++ b/src/plugins/data/config.ts @@ -32,7 +32,6 @@ import { schema, TypeOf } from '@osd/config-schema'; export const configSchema = schema.object({ enhancements: schema.object({ - enabled: schema.boolean({ defaultValue: false }), supportedAppNames: schema.arrayOf(schema.string(), { defaultValue: ['discover'], }), diff --git a/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx b/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx index 1cc5acd6f9de..bab5f1524584 100644 --- a/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx +++ b/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { i18n } from '@osd/i18n'; import { - EuiButtonIcon, + EuiSmallButtonIcon, EuiButtonIconProps, EuiText, EuiToolTip, @@ -33,7 +33,7 @@ export const DataSelectorRefresher: React.FC = Reac data-test-subj="sourceRefreshButtonToolTip" {...toolTipProps} > - const form = ( {mappedFilters.map((filter, i) => ( - - + this.toggleFilterSelected(i)} /> - + ))} ); @@ -115,18 +116,18 @@ export default class ApplyFiltersPopoverContent extends Component {form} - + - - + + - +
); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/generic_combo_box.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/generic_combo_box.tsx index 2df1b1e7c15b..59c906e2bb19 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/generic_combo_box.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/generic_combo_box.tsx @@ -28,7 +28,7 @@ * under the License. */ -import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; +import { EuiCompressedComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import React from 'react'; export interface GenericComboBoxProps { @@ -66,7 +66,7 @@ export function GenericComboBox(props: GenericComboBoxProps) { }; return ( - { - { {this.state.useCustomLabel && (
- - - +
)} @@ -181,7 +182,7 @@ class FilterEditorUI extends Component { - { id="data.filter.filterEditor.saveButtonLabel" defaultMessage="Save" /> - + - { id="data.filter.filterEditor.cancelButtonLabel" defaultMessage="Cancel" /> - + @@ -231,7 +232,7 @@ class FilterEditorUI extends Component { return ( - { isClearable={false} data-test-subj="filterIndexPatternsSelect" /> - + ); @@ -276,7 +277,7 @@ class FilterEditorUI extends Component { const fields = selectedIndexPattern ? getFilterableFields(selectedIndexPattern) : []; return ( - { className="globalFilterEditor__fieldInput" data-test-subj="filterFieldSuggestionList" /> - + ); } @@ -307,7 +308,7 @@ class FilterEditorUI extends Component { const { selectedField, selectedOperator } = this.state; const operators = selectedField ? getOperatorOptions(selectedField) : []; return ( - { isClearable={false} data-test-subj="filterOperatorList" /> - + ); } private renderCustomEditor() { return ( - { width="100%" height="250px" /> - + ); } diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_value_input.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_value_input.tsx index 624f478821db..74dcfa493b5f 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_value_input.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_value_input.tsx @@ -28,7 +28,7 @@ * under the License. */ -import { EuiFormRow } from '@elastic/eui'; +import { EuiCompressedFormRow } from '@elastic/eui'; import { InjectedIntl, injectI18n } from '@osd/i18n/react'; import { uniq } from 'lodash'; import React from 'react'; @@ -46,7 +46,7 @@ interface Props extends PhraseSuggestorProps { class PhraseValueInputUI extends PhraseSuggestorUI { public render() { return ( - { type={this.props.field ? this.props.field.type : 'string'} /> )} - + ); } diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/phrases_values_input.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/phrases_values_input.tsx index 0ac1af97a1cd..1e9e80012378 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/phrases_values_input.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/phrases_values_input.tsx @@ -28,7 +28,7 @@ * under the License. */ -import { EuiFormRow } from '@elastic/eui'; +import { EuiCompressedFormRow } from '@elastic/eui'; import { InjectedIntl, injectI18n } from '@osd/i18n/react'; import { uniq } from 'lodash'; import React from 'react'; @@ -48,7 +48,7 @@ class PhrasesValuesInputUI extends PhraseSuggestorUI { const { values, intl, onChange } = this.props; const options = values ? uniq([...values, ...suggestions]) : suggestions; return ( - { data-test-subj="filterParamsComboBox phrasesParamsComboxBox" delimiter="," /> - + ); } } diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx index 1bd1a653e027..9d7709a5f667 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx @@ -28,7 +28,11 @@ * under the License. */ -import { EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui'; +import { + EuiCompressedFieldNumber, + EuiCompressedFieldText, + EuiCompressedSelect, +} from '@elastic/eui'; import { InjectedIntl, injectI18n } from '@osd/i18n/react'; import { isEmpty } from 'lodash'; import React, { Component } from 'react'; @@ -53,7 +57,7 @@ class ValueInputTypeUI extends Component { switch (this.props.type) { case 'string': inputElement = ( - { break; case 'number': inputElement = ( - { break; case 'date': inputElement = ( - { break; case 'ip': inputElement = ( - { break; case 'boolean': inputElement = ( - { isOpen={this.state.isPopoverOpen} closePopover={this.closePopover} button={ - + + + DQL + + } + className="languageSelector" + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelPaddingSize="none" + > +
+
+ + + +
+
+
+
+ +`; + +exports[`LanguageSelector should select lucene if language is lucene 1`] = ` + + + + Lucene + + } + className="languageSelector" + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelPaddingSize="none" + > +
+
+ + + +
+
+
+
+
+`; diff --git a/src/plugins/data/public/ui/query_editor/_language_selector.scss b/src/plugins/data/public/ui/query_editor/_language_selector.scss index 2c44dc60ea23..d7847a96f0a2 100644 --- a/src/plugins/data/public/ui/query_editor/_language_selector.scss +++ b/src/plugins/data/public/ui/query_editor/_language_selector.scss @@ -3,6 +3,25 @@ * SPDX-License-Identifier: Apache-2.0 */ .languageSelector { - min-width: 140px; - border-bottom: $euiBorderThin !important; + height: 100%; + + .languageSelector__button { + &:hover { + text-decoration: none; // Prevents text underline on hover + } + } + + * { + font-size: small; + } +} + +.languageSelector__menuItem { + padding-left: 2px; + padding-right: 2px; + align-items: center; + + &:hover { + text-decoration: none; // Prevents text underline on hover + } } diff --git a/src/plugins/data/public/ui/query_editor/_query_editor.scss b/src/plugins/data/public/ui/query_editor/_query_editor.scss index fafb85a1bea5..8fc81308b533 100644 --- a/src/plugins/data/public/ui/query_editor/_query_editor.scss +++ b/src/plugins/data/public/ui/query_editor/_query_editor.scss @@ -15,17 +15,52 @@ // overflow: auto; } -.osdQueryEditor__languageWrapper { - :first-child { - box-shadow: none !important; - height: 100%; - border-radius: 0; +.osdQueryEditorFooter-isHidden { + display: none; +} + +.osdQueryEditorFooter { + color: $euiTextSubduedColor; // Apply the subdued color to all text in this class + height: 25px; + + * { + color: inherit; + font-size: $euiFontSizeXS; + align-items: center; } } +.osdQueryEditor__collapseWrapper { + box-shadow: $euiTextSubduedColor; +} + +.osdQueryEditor__languageWrapper { + align-items: center; + justify-content: center; + max-height: 40px; + border: $euiBorderThin; +} + .osdQueryEditor__dataSourceWrapper { + .dataSourceSelect { + border-bottom: $euiBorderThin !important; + + :first-child { + box-shadow: none !important; + height: 100%; + border-radius: 0; + } + + div:is([class$="--group"]) { + padding: 0 !important; + } + } +} + +.osdQueryEditor__dataSetWrapper { .dataExplorerDSSelect { border-bottom: $euiBorderThin !important; + max-width: 375px; div:is([class$="--group"]) { padding: 0 !important; @@ -37,6 +72,20 @@ } } +.osdQueryEditor__prependWrapper { + box-shadow: $euiTextSubduedColor; +} + +.osdQueryEditor__prependWrapper-isCollapsed { + box-shadow: none; +} + +.osdQueryEditor--updateButtonWrapper { + :first-child { + min-width: 0 !important; + } +} + @include euiBreakpoint("xs", "s") { .osdQueryEditor--withDatePicker { > :first-child { diff --git a/src/plugins/data/public/ui/query_editor/language_selector.test.tsx b/src/plugins/data/public/ui/query_editor/language_selector.test.tsx index da3543deb74f..f61134211a40 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.test.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.test.tsx @@ -8,7 +8,7 @@ import { QueryLanguageSelector } from './language_selector'; import { OpenSearchDashboardsContextProvider } from 'src/plugins/opensearch_dashboards_react/public'; import { coreMock } from '../../../../../core/public/mocks'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { EuiComboBox } from '@elastic/eui'; +import { EuiCompressedComboBox } from '@elastic/eui'; import { QueryEnhancement } from '../types'; const startMock = coreMock.createStart(); @@ -53,14 +53,7 @@ describe('LanguageSelector', () => { }, }) ); - const euiComboBox = component.find(EuiComboBox); - expect(euiComboBox.prop('selectedOptions')).toEqual( - expect.arrayContaining([ - { - label: 'Lucene', - }, - ]) - ); + expect(component).toMatchSnapshot(); }); it('should select DQL if language is kuery', () => { @@ -72,13 +65,6 @@ describe('LanguageSelector', () => { }, }) ); - const euiComboBox = component.find(EuiComboBox); - expect(euiComboBox.prop('selectedOptions')).toEqual( - expect.arrayContaining([ - { - label: 'DQL', - }, - ]) - ); + expect(component).toMatchSnapshot(); }); }); diff --git a/src/plugins/data/public/ui/query_editor/language_selector.tsx b/src/plugins/data/public/ui/query_editor/language_selector.tsx index 7ea82fe2b24e..ce7c1e17178d 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.tsx @@ -3,16 +3,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiComboBox, EuiComboBoxOptionOption, PopoverAnchorPosition } from '@elastic/eui'; +import { + PopoverAnchorPosition, + EuiContextMenuPanel, + EuiPopover, + EuiButtonEmpty, + EuiContextMenuItem, +} from '@elastic/eui'; import { i18n } from '@osd/i18n'; -import React from 'react'; +import React, { useState } from 'react'; import { getUiService } from '../../services'; -interface Props { +export interface QueryLanguageSelectorProps { language: string; onSelectLanguage: (newLanguage: string) => void; anchorPosition?: PopoverAnchorPosition; appName?: string; + isFooter?: boolean; } const mapExternalLanguageToOptions = (language: string) => { @@ -22,7 +29,13 @@ const mapExternalLanguageToOptions = (language: string) => { }; }; -export const QueryLanguageSelector = (props: Props) => { +export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { + const [isPopoverOpen, setPopover] = useState(false); + + const onButtonClick = () => { + setPopover(!isPopoverOpen); + }; + const dqlLabel = i18n.translate('data.query.queryEditor.dqlLanguageName', { defaultMessage: 'DQL', }); @@ -30,7 +43,7 @@ export const QueryLanguageSelector = (props: Props) => { defaultMessage: 'Lucene', }); - const languageOptions: EuiComboBoxOptionOption[] = [ + const languageOptions = [ { label: dqlLabel, value: 'kuery', @@ -64,25 +77,58 @@ export const QueryLanguageSelector = (props: Props) => { )?.label as string) ?? languageOptions[0].label, }; - const handleLanguageChange = (newLanguage: EuiComboBoxOptionOption[]) => { - const queryLanguage = newLanguage[0].value as string; - props.onSelectLanguage(queryLanguage); - uiService.Settings.setUserQueryLanguage(queryLanguage); + const handleLanguageChange = (newLanguage: string) => { + props.onSelectLanguage(newLanguage); + uiService.Settings.setUserQueryLanguage(newLanguage); }; uiService.Settings.setUserQueryLanguage(props.language); + const languageOptionsMenu = languageOptions.map((language) => { + return ( + { + setPopover(false); + handleLanguageChange(language.value); + }} + > + {language.label} + + ); + }); return ( - + button={ + + {selectedLanguage.label} + + } + isOpen={isPopoverOpen} + closePopover={() => setPopover(false)} + panelPaddingSize="none" + anchorPosition={props.anchorPosition ?? 'downLeft'} + > + option.label === selectedLanguage.label + )} + size="s" + items={languageOptionsMenu} + /> + ); }; + +// Needed for React.lazy +// eslint-disable-next-line import/no-default-export +export default QueryLanguageSelector; diff --git a/src/plugins/data/public/ui/query_editor/query_editor.tsx b/src/plugins/data/public/ui/query_editor/query_editor.tsx index a12cb3052f53..9302f397eb09 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor.tsx @@ -3,12 +3,27 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiFlexGroup, EuiFlexItem, htmlIdGenerator, PopoverAnchorPosition } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormRow, + htmlIdGenerator, + PopoverAnchorPosition, +} from '@elastic/eui'; import classNames from 'classnames'; import { isEqual } from 'lodash'; import React, { Component, createRef, RefObject } from 'react'; +import { monaco } from '@osd/monaco'; import { Settings } from '..'; -import { DataSource, IDataPluginServices, IIndexPattern, Query, TimeRange } from '../..'; +import { + DataSource, + IDataPluginServices, + IFieldType, + IIndexPattern, + Query, + TimeRange, +} from '../..'; import { CodeEditor, OpenSearchDashboardsReactContextValue, @@ -20,12 +35,15 @@ import { DataSettings } from '../types'; import { fetchIndexPatterns } from './fetch_index_patterns'; import { QueryLanguageSelector } from './language_selector'; import { QueryEditorExtensions } from './query_editor_extensions'; - +import { QueryEditorBtnCollapse } from './query_editor_btn_collapse'; export interface QueryEditorProps { indexPatterns: Array; dataSource?: DataSource; query: Query; + container?: HTMLDivElement; + dataSourceContainerRef?: React.RefCallback; containerRef?: React.RefCallback; + languageSelectorContainerRef?: React.RefCallback; settings: Settings; disableAutoFocus?: boolean; screenTitle?: string; @@ -46,6 +64,8 @@ export interface QueryEditorProps { queryLanguage?: string; headerClassName?: string; bannerClassName?: string; + footerClassName?: string; + filterBar?: any; } interface Props extends QueryEditorProps { @@ -54,10 +74,14 @@ interface Props extends QueryEditorProps { interface State { isDataSourcesVisible: boolean; + isDataSetsVisible: boolean; isSuggestionsVisible: boolean; index: number | null; suggestions: QuerySuggestion[]; indexPatterns: IIndexPattern[]; + isCollapsed: boolean; + timeStamp: IFieldType | null; + lineCount: number | undefined; } const KEY_CODES = { @@ -77,14 +101,18 @@ const KEY_CODES = { // eslint-disable-next-line import/no-default-export export default class QueryEditorUI extends Component { public state: State = { - isDataSourcesVisible: true, + isDataSourcesVisible: false, + isDataSetsVisible: true, isSuggestionsVisible: false, index: null, suggestions: [], indexPatterns: [], + isCollapsed: false, // default to expand mode + timeStamp: null, + lineCount: undefined, }; - public inputRef: HTMLElement | null = null; + public inputRef: monaco.editor.IStandaloneCodeEditor | null = null; private persistedLog: PersistedLog | undefined; private abortController?: AbortController; @@ -172,6 +200,12 @@ export default class QueryEditorUI extends Component { private onInputChange = (value: string) => { this.onQueryStringChange(value); + + if (!this.inputRef) return; + + const currentLineCount = this.inputRef.getModel()?.getLineCount(); + if (this.state.lineCount === currentLineCount) return; + this.setState({ lineCount: currentLineCount }); }; private onClickInput = (event: React.MouseEvent) => { @@ -212,9 +246,9 @@ export default class QueryEditorUI extends Component { : undefined; this.onChange(newQuery, dateRange); this.onSubmit(newQuery, dateRange); + this.setState({ isDataSetsVisible: enhancement?.searchBar?.showDataSetsSelector ?? true }); this.setState({ isDataSourcesVisible: enhancement?.searchBar?.showDataSourcesSelector ?? true, - isDataSetsVisible: enhancement?.searchBar?.showDataSetsSelector ?? true, }); }; @@ -228,15 +262,19 @@ export default class QueryEditorUI extends Component { private initDataSourcesVisibility = () => { if (this.componentIsUnmounting) return; - return this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar - ?.showDataSourcesSelector; + const isDataSourcesVisible = + this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar + ?.showDataSourcesSelector ?? true; + this.setState({ isDataSourcesVisible }); }; private initDataSetsVisibility = () => { if (this.componentIsUnmounting) return; - return this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar - ?.showDataSetsSelector; + const isDataSetsVisible = + this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar + ?.showDataSetsSelector ?? true; + this.setState({ isDataSetsVisible }); }; public onMouseEnterSuggestion = (index: number) => { @@ -253,10 +291,8 @@ export default class QueryEditorUI extends Component { this.initPersistedLog(); // this.fetchIndexPatterns().then(this.updateSuggestions); - this.setState({ - isDataSourcesVisible: this.initDataSourcesVisibility() || true, - isDataSetsVisible: this.initDataSetsVisibility() || true, - }); + this.initDataSourcesVisibility(); + this.initDataSetsVisibility(); } public componentDidUpdate(prevProps: Props) { @@ -279,10 +315,65 @@ export default class QueryEditorUI extends Component { } }; + editorDidMount = (editor: monaco.editor.IStandaloneCodeEditor) => { + this.setState({ lineCount: editor.getModel()?.getLineCount() }); + this.inputRef = editor; + }; + + private onSingleLineInputChange = (value: string) => { + // Replace new lines with an empty string to prevent multi-line input + this.onQueryStringChange(value.replace(/[\r\n]+/gm, '')); + + this.setState({ lineCount: undefined }); + }; + + singleLineEditorDidMount = (editor: monaco.editor.IStandaloneCodeEditor) => { + this.inputRef = editor; + + const editorNode = editor.getDomNode(); + if (editorNode) { + const containerId = 'single-line-editor-wrapper'; + const style = document.createElement('style'); + const customCursorHeight = 20; + // eslint-disable-next-line no-unsanitized/property + style.innerHTML = ` + .${containerId} .monaco-editor .view-lines { + padding-left: 15px; + } + .${containerId} .monaco-editor .cursor { + height: ${customCursorHeight}px !important; + margin-top: ${(38 - customCursorHeight) / 2}px !important; + } + `; + + document.head.appendChild(style); + } + const handleEnterPress = () => { + this.onSubmit(this.props.query); + }; + + const disposable = editor.onKeyDown((e) => { + if (e.keyCode === monaco.KeyCode.Enter) { + // Prevent default Enter key behavior + e.preventDefault(); + handleEnterPress(); + } + }); + + // Optional: Cleanup on component unmount + return () => { + disposable.dispose(); + }; + }; + public render() { const className = classNames(this.props.className); const headerClassName = classNames('osdQueryEditorHeader', this.props.headerClassName); const bannerClassName = classNames('osdQueryEditorBanner', this.props.bannerClassName); + const footerClassName = classNames('osdQueryEditorFooter', this.props.footerClassName); + + const useQueryEditor = + this.props.query.language !== 'kuery' && this.props.query.language !== 'lucene'; return (
@@ -290,43 +381,142 @@ export default class QueryEditorUI extends Component { - {this.props.prepend} - - + this.setState({ isCollapsed: !this.state.isCollapsed })} + isCollapsed={!this.state.isCollapsed} /> {this.state.isDataSourcesVisible && ( - + +
+ + )} + + {this.state.isDataSetsVisible && ( +
)} + + + {(this.state.isCollapsed || !useQueryEditor) && ( + +
+ +
+
+ )} + {!useQueryEditor && ( + +
+ +
+
+ )} +
+
+ + {this.props.prepend} + +
- + {!this.state.isCollapsed && useQueryEditor && ( + + )} + +
+ + + + + + + {this.state.lineCount} {this.state.lineCount === 1 ? 'line' : 'lines'} + + + {typeof this.props.indexPatterns?.[0] !== 'string' && + '@' + this.props.indexPatterns?.[0].timeFieldName} + + +
+ + {!this.state.isCollapsed && ( + {this.props.filterBar} + )} {this.renderQueryEditorExtensions()}
diff --git a/src/plugins/data/public/ui/query_editor/query_editor_btn_collapse.tsx b/src/plugins/data/public/ui/query_editor/query_editor_btn_collapse.tsx new file mode 100644 index 000000000000..1bde59570fdd --- /dev/null +++ b/src/plugins/data/public/ui/query_editor/query_editor_btn_collapse.tsx @@ -0,0 +1,31 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { i18n } from '@osd/i18n'; +import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; + +export interface Props { + onClick: () => void; + isCollapsed: boolean; +} + +export function QueryEditorBtnCollapse({ onClick, isCollapsed }: Props) { + const label = i18n.translate('queryEditor.collapse', { + defaultMessage: 'Toggle query editor', + }); + return ( + + + + ); +} diff --git a/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.test.tsx b/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.test.tsx index b3c8747e833d..6ff348fbf3bd 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.test.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.test.tsx @@ -5,6 +5,7 @@ import { render, waitFor } from '@testing-library/react'; import React, { ComponentProps } from 'react'; +import { of } from 'rxjs'; import { IIndexPattern } from '../../../../common'; import { QueryEditorExtension } from './query_editor_extension'; @@ -39,7 +40,7 @@ describe('QueryEditorExtension', () => { config: { id: 'test-extension', order: 1, - isEnabled: isEnabledMock, + isEnabled$: isEnabledMock, getComponent: getComponentMock, getBanner: getBannerMock, }, @@ -56,7 +57,7 @@ describe('QueryEditorExtension', () => { }); it('renders correctly when isEnabled is true', async () => { - isEnabledMock.mockResolvedValue(true); + isEnabledMock.mockReturnValue(of(true)); getComponentMock.mockReturnValue(
Test Component
); getBannerMock.mockReturnValue(
Test Banner
); @@ -72,7 +73,7 @@ describe('QueryEditorExtension', () => { }); it('does not render when isEnabled is false', async () => { - isEnabledMock.mockResolvedValue(false); + isEnabledMock.mockReturnValue(of(false)); getComponentMock.mockReturnValue(
Test Component
); const { queryByText } = render(); diff --git a/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.tsx b/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.tsx index 30b02f0f15dc..78b402df7c65 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor_extensions/query_editor_extension.tsx @@ -6,6 +6,7 @@ import { EuiErrorBoundary } from '@elastic/eui'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import ReactDOM from 'react-dom'; +import { Observable } from 'rxjs'; import { IIndexPattern } from '../../../../common'; import { DataSource } from '../../../data_sources/datasource'; @@ -33,7 +34,7 @@ export interface QueryEditorExtensionDependencies { export interface QueryEditorExtensionConfig { /** - * The id for the search bar extension. + * The id for the query editor extension. */ id: string; /** @@ -41,26 +42,25 @@ export interface QueryEditorExtensionConfig { */ order: number; /** - * A function that determines if the search bar extension is enabled and should be rendered on UI. + * A function that determines if the query editor extension is enabled and should be rendered on UI. * @returns whether the extension is enabled. */ - isEnabled: (dependencies: QueryEditorExtensionDependencies) => Promise; + isEnabled$: (dependencies: QueryEditorExtensionDependencies) => Observable; /** - * A function that returns the search bar extension component. The component + * A function that returns the query editor extension component. The component * will be displayed on top of the query editor in the search bar. * @param dependencies - The dependencies required for the extension. - * @returns The component the search bar extension. + * @returns The component the query editor extension. */ getComponent?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null; /** - * A function that returns the search bar extension banner. The banner is a + * A function that returns the query editor extension banner. The banner is a * component that will be displayed on top of the search bar. * @param dependencies - The dependencies required for the extension. - * @returns The component the search bar extension. + * @returns The component the query editor extension. */ getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null; } - const QueryEditorExtensionPortal: React.FC<{ container: Element }> = (props) => { if (!props.children) return null; @@ -92,9 +92,10 @@ export const QueryEditorExtension: React.FC = (props) }, []); useEffect(() => { - props.config.isEnabled(props.dependencies).then((enabled) => { + const subscription = props.config.isEnabled$(props.dependencies).subscribe((enabled) => { if (isMounted.current) setIsEnabled(enabled); }); + return () => subscription.unsubscribe(); }, [props.dependencies, props.config]); if (!isEnabled) return null; diff --git a/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx b/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx index be75c44ece60..8304fdc252ee 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx @@ -4,17 +4,17 @@ */ import dateMath from '@elastic/datemath'; import { - EuiFieldText, + EuiButton, + EuiCompressedFieldText, EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker, - EuiSuperUpdateButton, OnRefreshProps, prettyDuration, } from '@elastic/eui'; import classNames from 'classnames'; import { compact, isEqual } from 'lodash'; -import React, { useRef, useState } from 'react'; +import React, { useState } from 'react'; import { DataSource, IDataPluginServices, @@ -28,7 +28,7 @@ import { withOpenSearchDashboards, } from '../../../../opensearch_dashboards_react/public'; import { UI_SETTINGS } from '../../../common'; -import { fromUser, getQueryLog, PersistedLog } from '../../query'; +import { getQueryLog, PersistedLog } from '../../query'; import { Settings } from '../types'; import { NoDataPopover } from './no_data_popover'; import QueryEditorUI from './query_editor'; @@ -38,6 +38,7 @@ const QueryEditor = withOpenSearchDashboards(QueryEditorUI); // @internal export interface QueryEditorTopRowProps { query?: Query; + dataSourceContainerRef?: React.RefCallback; containerRef?: React.RefCallback; settings?: Settings; onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void; @@ -49,7 +50,7 @@ export interface QueryEditorTopRowProps { indexPatterns?: Array; dataSource?: DataSource; isLoading?: boolean; - prepend?: React.ComponentProps['prepend']; + prepend?: React.ComponentProps['prepend']; showQueryEditor?: boolean; showDatePicker?: boolean; dateRangeFrom?: string; @@ -74,8 +75,6 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { const opensearchDashboards = useOpenSearchDashboards(); const { uiSettings, storage, appName } = opensearchDashboards.services; - const isDataSourceReadOnly = uiSettings.get(UI_SETTINGS.QUERY_DATA_SOURCE_READONLY); - const queryLanguage = props.query && props.query.language; const queryUiEnhancement = (queryLanguage && @@ -192,17 +191,7 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { } function isValidQuery(query: Query | undefined) { - if (!query || !query.query) return false; - return ( - !Array.isArray(props.indexPatterns!) || - compact(props.indexPatterns!).length === 0 || - !isDataSourceReadOnly || - fromUser(query!.query).includes( - typeof props.indexPatterns[0] === 'string' - ? props.indexPatterns[0] - : props.indexPatterns[0].title - ) - ); + if (query && query.query) return true; } function getQueryStringInitialValue(language: string) { @@ -234,6 +223,7 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { dataSource={props.dataSource} prepend={props.prepend} query={parsedQuery} + dataSourceContainerRef={props.dataSourceContainerRef} containerRef={props.containerRef} settings={props.settings!} screenTitle={props.screenTitle} @@ -245,6 +235,7 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { className="osdQueryEditor" dataTestSubj={props.dataTestSubj} queryLanguage={queryLanguage} + filterBar={props.filterBar} />
); @@ -285,13 +276,16 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { const button = props.customSubmitButton ? ( React.cloneElement(props.customSubmitButton, { onClick: onClickSubmitButton }) ) : ( - + className="euiSuperUpdateButton" + iconType="play" + > + {props.isDirty ? 'Refresh' : 'Run'} + ); if (!shouldRenderDatePicker()) { @@ -373,12 +367,15 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { direction="column" justifyContent="flexEnd" > + + + {renderUpdateButton()} + + {renderQueryEditor()} - - {props.filterBar} + {renderSharingMetaFields()} - {renderUpdateButton()} diff --git a/src/plugins/data/public/ui/query_string_input/language_switcher.tsx b/src/plugins/data/public/ui/query_string_input/language_switcher.tsx index d9c398acb639..c31a40db8ddb 100644 --- a/src/plugins/data/public/ui/query_string_input/language_switcher.tsx +++ b/src/plugins/data/public/ui/query_string_input/language_switcher.tsx @@ -32,12 +32,12 @@ import { i18n } from '@osd/i18n'; import { EuiButtonEmpty, EuiForm, - EuiFormRow, + EuiCompressedFormRow, EuiLink, EuiPopover, EuiPopoverTitle, EuiSpacer, - EuiSwitch, + EuiCompressedSwitch, EuiText, PopoverAnchorPosition, } from '@elastic/eui'; @@ -122,8 +122,8 @@ export function QueryLanguageSwitcher(props: Props) { - - + - +
diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index c0ec95325a71..72b28830652b 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -39,7 +39,7 @@ import { EuiFlexItem, EuiLink, EuiSuperDatePicker, - EuiFieldText, + EuiCompressedFieldText, prettyDuration, } from '@elastic/eui'; // @ts-ignore @@ -70,7 +70,7 @@ export interface QueryBarTopRowProps { screenTitle?: string; indexPatterns?: Array; isLoading?: boolean; - prepend?: React.ComponentProps['prepend']; + prepend?: React.ComponentProps['prepend']; showQueryInput?: boolean; showDatePicker?: boolean; dateRangeFrom?: string; diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index b2750e855b0f..dbbaad9cc3d2 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -33,7 +33,7 @@ import { i18n } from '@osd/i18n'; import classNames from 'classnames'; import { - EuiTextArea, + EuiCompressedTextArea, EuiOutsideClickDetector, PopoverAnchorPosition, EuiFlexGroup, @@ -642,7 +642,7 @@ export default class QueryStringInputUI extends Component { className="euiFormControlLayout__childrenWrapper osdQueryBar__textareaWrap" ref={this.queryBarInputDivRefInstance} > - { isInvalid={this.props.isInvalid} > {this.getQueryString()} - +
- + {savedQueryDescriptionText} - - + - - + - - { @@ -195,10 +195,10 @@ export function SaveQueryForm({ }} data-test-subj="saveQueryFormDescription" /> - + {showFilterOption && ( - - + - + )} {showTimeFilterOption && ( - - + - + )} ); @@ -247,13 +247,13 @@ export function SaveQueryForm({ {saveQueryForm} - + {i18n.translate('data.search.searchBar.savedQueryFormCancelButtonText', { defaultMessage: 'Cancel', })} - + - + ); diff --git a/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx b/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx index da7c25254adb..4e4dd26cec47 100644 --- a/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx +++ b/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx @@ -32,6 +32,7 @@ import { EuiPopover, EuiPopoverTitle, EuiPopoverFooter, + EuiSmallButtonEmpty, EuiButtonEmpty, EuiButton, EuiFlexGroup, @@ -171,7 +172,7 @@ export function SavedQueryManagementComponent({ }; const savedQueryPopoverButton = ( - - - + ); const savedQueryRows = () => { diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx index 9baeab489d4b..244f4296216c 100644 --- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx @@ -48,6 +48,7 @@ interface StatefulSearchBarDeps { data: Omit; storage: IStorageWrapper; settings: Settings; + setDataSourceContainerRef: (ref: HTMLDivElement | null) => void; setContainerRef: (ref: HTMLDivElement | null) => void; } @@ -138,6 +139,7 @@ export function createSearchBar({ storage, data, settings, + setDataSourceContainerRef, setContainerRef, }: StatefulSearchBarDeps) { // App name should come from the core application service. @@ -174,6 +176,12 @@ export function createSearchBar({ notifications: core.notifications, }); + const dataSourceContainerRef = useCallback((node) => { + if (node) { + setDataSourceContainerRef(node); + } + }, []); + const containerRef = useCallback((node) => { if (node) { setContainerRef(node); @@ -220,6 +228,7 @@ export function createSearchBar({ filters={filters} query={query} settings={settings} + dataSourceContainerRef={dataSourceContainerRef} containerRef={containerRef} onFiltersUpdated={defaultFiltersUpdated(data.query)} onRefreshChange={defaultOnRefreshChange(data.query)} diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 54e39fcb0b8d..11914f134443 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -80,6 +80,7 @@ export interface SearchBarOwnProps { // Query bar - should be in SearchBarInjectedDeps query?: Query; settings?: Settings; + dataSourceContainerRef?: React.RefCallback; containerRef?: React.RefCallback; // Show when user has privileges to save showSaveQuery?: boolean; @@ -490,6 +491,7 @@ class SearchBarUI extends Component { queryEditor = ( , private readonly queryEditorExtensionMap: Record ) { - this.isEnabled = this.config.enabled; + this.isEnabled = true; this.setUserQueryEnhancementsEnabled(this.isEnabled); this.enhancedAppNames = this.isEnabled ? this.config.supportedAppNames : []; } diff --git a/src/plugins/data/public/ui/shard_failure_modal/__snapshots__/shard_failure_modal.test.tsx.snap b/src/plugins/data/public/ui/shard_failure_modal/__snapshots__/shard_failure_modal.test.tsx.snap index f7f3d1c1fbd0..ef9d1f0fb923 100644 --- a/src/plugins/data/public/ui/shard_failure_modal/__snapshots__/shard_failure_modal.test.tsx.snap +++ b/src/plugins/data/public/ui/shard_failure_modal/__snapshots__/shard_failure_modal.test.tsx.snap @@ -173,7 +173,7 @@ exports[`ShardFailureModal renders matching snapshot given valid properties 1`] > - - + `; diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx index 6c7ff95f29f8..f4b7d1fd0980 100644 --- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx +++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx @@ -35,12 +35,12 @@ import { EuiCodeBlock, EuiTabbedContent, EuiCopy, - EuiButton, + EuiSmallButton, EuiModalBody, EuiModalHeader, EuiModalHeaderTitle, EuiModalFooter, - EuiButtonEmpty, + EuiSmallButtonEmpty, EuiCallOut, } from '@elastic/eui'; import { SearchResponse } from 'elasticsearch'; @@ -121,21 +121,21 @@ export function ShardFailureModal({ request, response, title, onClose }: Props) {(copy) => ( - + - + )} - onClose()} fill data-test-sub="closeShardFailureModal"> + onClose()} fill data-test-sub="closeShardFailureModal"> - + ); diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_table.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_table.tsx index 2414a4095910..057a17c4a523 100644 --- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_table.tsx +++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_table.tsx @@ -30,7 +30,7 @@ import React, { useState, ReactElement } from 'react'; // @ts-ignore -import { EuiInMemoryTable, EuiButtonIcon } from '@elastic/eui'; +import { EuiInMemoryTable, EuiSmallButtonIcon } from '@elastic/eui'; // @ts-ignore import { RIGHT_ALIGNMENT } from '@elastic/eui/lib/services'; import { i18n } from '@osd/i18n'; @@ -74,7 +74,7 @@ export function ShardFailureTable({ failures }: { failures: ShardFailure[] }) { ); return ( - { // toggle displaying the expanded view of the given list item const map = Object.assign({}, expandMap); diff --git a/src/plugins/data/public/ui/types.ts b/src/plugins/data/public/ui/types.ts index e273019c3908..afa0c8130504 100644 --- a/src/plugins/data/public/ui/types.ts +++ b/src/plugins/data/public/ui/types.ts @@ -21,7 +21,8 @@ export interface QueryEnhancement { // Leave blank to support all data sources // supportedDataSourceTypes?: Record; searchBar?: { - showDataSourceSelector?: boolean; + showDataSetsSelector?: boolean; + showDataSourcesSelector?: boolean; showQueryInput?: boolean; showFilterBar?: boolean; showDatePicker?: boolean; @@ -66,5 +67,6 @@ export interface IUiStart { SearchBar: React.ComponentType; SuggestionsComponent: React.ComponentType; Settings: Settings; + dataSourceContainer$: Observable; container$: Observable; } diff --git a/src/plugins/data/public/ui/ui_service.ts b/src/plugins/data/public/ui/ui_service.ts index e2dcae737acc..1e0e6be8b78c 100644 --- a/src/plugins/data/public/ui/ui_service.ts +++ b/src/plugins/data/public/ui/ui_service.ts @@ -29,6 +29,7 @@ export class UiService implements Plugin { enhancementsConfig: ConfigSchema['enhancements']; private queryEnhancements: Map = new Map(); private queryEditorExtensionMap: Record = {}; + private dataSourceContainer$ = new BehaviorSubject(null); private container$ = new BehaviorSubject(null); constructor(initializerContext: PluginInitializerContext) { @@ -41,7 +42,6 @@ export class UiService implements Plugin { return { __enhance: (enhancements?: UiEnhancements) => { if (!enhancements) return; - if (!this.enhancementsConfig.enabled) return; if (enhancements.query && enhancements.query.language) { this.queryEnhancements.set(enhancements.query.language, enhancements.query); } @@ -62,6 +62,10 @@ export class UiService implements Plugin { queryEditorExtensionMap: this.queryEditorExtensionMap, }); + const setDataSourceContainerRef = (ref: HTMLDivElement | null) => { + this.dataSourceContainer$.next(ref); + }; + const setContainerRef = (ref: HTMLDivElement | null) => { this.container$.next(ref); }; @@ -71,6 +75,7 @@ export class UiService implements Plugin { data: dataServices, storage, settings: Settings, + setDataSourceContainerRef, setContainerRef, }); @@ -79,6 +84,7 @@ export class UiService implements Plugin { SearchBar, SuggestionsComponent, Settings, + dataSourceContainer$: this.dataSourceContainer$, container$: this.container$, }; } diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index ca24151e681d..95439335e18e 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -709,7 +709,7 @@ export function getUiSettings(): Record> { name: i18n.translate('data.advancedSettings.query.enhancements.enableTitle', { defaultMessage: 'Enable query enhancements', }), - value: false, + value: true, description: i18n.translate('data.advancedSettings.query.enhancements.enableText', { defaultMessage: ` Experimental: @@ -750,19 +750,6 @@ export function getUiSettings(): Record> { category: ['search'], schema: schema.string(), }, - [UI_SETTINGS.QUERY_DATA_SOURCE_READONLY]: { - name: i18n.translate('data.advancedSettings.query.dataSource.readOnlyTitle', { - defaultMessage: 'Read-only data source in query editor', - }), - value: true, - description: i18n.translate('data.advancedSettings.query.dataSource.readOnlyText', { - defaultMessage: - 'When enabled, the search bar prevents modifying the data source in the query input. ' + - 'Experimental: Requires query enhancements enabled.', - }), - category: ['search'], - schema: schema.boolean(), - }, [UI_SETTINGS.SEARCH_QUERY_LANGUAGE_BLOCKLIST]: { name: i18n.translate('data.advancedSettings.searchQueryLanguageBlocklistTitle', { defaultMessage: 'Additional query languages blocklist', diff --git a/src/plugins/data_source_management/public/components/create_button/__snapshots__/create_button.test.tsx.snap b/src/plugins/data_source_management/public/components/create_button/__snapshots__/create_button.test.tsx.snap index f0e2965c6678..03c20a8093ee 100644 --- a/src/plugins/data_source_management/public/components/create_button/__snapshots__/create_button.test.tsx.snap +++ b/src/plugins/data_source_management/public/components/create_button/__snapshots__/create_button.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`CreateButton should render normally 1`] = ` - - + `; diff --git a/src/plugins/data_source_management/public/components/create_button/create_button.tsx b/src/plugins/data_source_management/public/components/create_button/create_button.tsx index 7c893af0209d..303379a0c890 100644 --- a/src/plugins/data_source_management/public/components/create_button/create_button.tsx +++ b/src/plugins/data_source_management/public/components/create_button/create_button.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { History } from 'history'; -import { EuiButton } from '@elastic/eui'; +import { EuiSmallButton } from '@elastic/eui'; import { FormattedMessage } from '@osd/i18n/react'; interface Props { @@ -17,7 +17,7 @@ interface Props { export const CreateButton = ({ history, isEmptyState, dataTestSubj }: Props) => { return ( - history.push('/create')} @@ -26,6 +26,6 @@ export const CreateButton = ({ history, isEmptyState, dataTestSubj }: Props) => id="dataSourcesManagement.dataSourceListing.createButton" defaultMessage="Create data source connection" /> - + ); }; diff --git a/src/plugins/data_source_management/public/components/create_data_source_wizard/components/create_form/__snapshots__/create_data_source_form.test.tsx.snap b/src/plugins/data_source_management/public/components/create_data_source_wizard/components/create_form/__snapshots__/create_data_source_form.test.tsx.snap index 2bb1bd8053d7..be2a18192fe9 100644 --- a/src/plugins/data_source_management/public/components/create_data_source_wizard/components/create_form/__snapshots__/create_data_source_form.test.tsx.snap +++ b/src/plugins/data_source_management/public/components/create_data_source_wizard/components/create_form/__snapshots__/create_data_source_form.test.tsx.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Datasource Management: Create Datasource form with different authType configurations should render normally with all authMethod combinations 1`] = ` -