diff --git a/public/app/features/datasources/components/picker/DataSourceDropdown.tsx b/public/app/features/datasources/components/picker/DataSourceDropdown.tsx index f2f1f91e45d..e2dcd6831a3 100644 --- a/public/app/features/datasources/components/picker/DataSourceDropdown.tsx +++ b/public/app/features/datasources/components/picker/DataSourceDropdown.tsx @@ -8,6 +8,7 @@ import { usePopper } from 'react-popper'; import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; import { DataSourceJsonData } from '@grafana/schema'; import { Button, CustomScrollbar, Icon, Input, ModalsController, Portal, useStyles2 } from '@grafana/ui'; +import config from 'app/core/config'; import { DataSourceList } from './DataSourceList'; import { DataSourceLogo, DataSourceLogoPlaceHolder } from './DataSourceLogo'; @@ -157,7 +158,7 @@ const PickerContent = React.forwardRef((prop
- {onClickAddCSV && ( + {onClickAddCSV && config.featureToggles.editPanelCSVDragAndDrop && ( diff --git a/public/app/features/datasources/components/picker/DataSourceModal.tsx b/public/app/features/datasources/components/picker/DataSourceModal.tsx index 6c0a191923f..142b6a4c20b 100644 --- a/public/app/features/datasources/components/picker/DataSourceModal.tsx +++ b/public/app/features/datasources/components/picker/DataSourceModal.tsx @@ -43,64 +43,62 @@ export function DataSourceModal({ closeOnBackdropClick={true} isOpen={true} className={styles.modal} + contentClassName={styles.modalContent} onClickBackdrop={onDismiss} onDismiss={onDismiss} > -
-
- } - placeholder="Search data source" - onChange={(e) => setSearch(e.currentTarget.value)} +
+ } + placeholder="Search data source" + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + ds.name.includes(search) && !ds.meta.builtIn} + onChange={onChange} + current={current} /> - - ds.name.toLowerCase().includes(search.toLowerCase()) && ds.name !== '-- Grafana --'} - onChange={onChange} - current={current} - /> - + +
+
+
+ !!ds.meta.builtIn} + dashboard + mixed + onChange={onChange} + current={current} + /> + {enableFileUpload && ( + undefined} + options={{ + maxSize: DFImport.maxFileSize, + multiple: false, + accept: DFImport.acceptedFiles, + ...fileUploadOptions, + onDrop: (...args) => { + fileUploadOptions?.onDrop?.(...args); + onDismiss(); + }, + }} + > + + + )}
-
-
- !!ds.meta.builtIn} - dashboard - mixed - onChange={onChange} - current={current} - /> - {enableFileUpload && ( - undefined} - options={{ - maxSize: DFImport.maxFileSize, - multiple: false, - accept: DFImport.acceptedFiles, - ...fileUploadOptions, - onDrop: (...args) => { - fileUploadOptions?.onDrop?.(...args); - onDismiss(); - }, - }} - > - - - )} -
-
- - Configure a new data source - -
+
+ + Configure a new data source +
@@ -112,12 +110,12 @@ function getDataSourceModalStyles(theme: GrafanaTheme2) { modal: css` width: 80%; height: 80%; + max-width: 1200px; + max-height: 900px; `, modalContent: css` display: flex; flex-direction: row; - justify-content: space-between; - align-items: stretch; height: 100%; `, leftColumn: css` @@ -133,7 +131,6 @@ function getDataSourceModalStyles(theme: GrafanaTheme2) { flex-direction: column; width: 50%; height: 100%; - padding: ${theme.spacing(1)}; justify-items: space-evenly; align-items: stretch; padding-left: ${theme.spacing(1)}; diff --git a/public/app/features/query/components/QueryGroup.tsx b/public/app/features/query/components/QueryGroup.tsx index eefdb6404a0..42233e2aa06 100644 --- a/public/app/features/query/components/QueryGroup.tsx +++ b/public/app/features/query/components/QueryGroup.tsx @@ -15,13 +15,14 @@ import { PanelData, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { getDataSourceSrv } from '@grafana/runtime'; +import { getDataSourceSrv, locationService } from '@grafana/runtime'; import { Button, CustomScrollbar, HorizontalGroup, InlineFormLabel, Modal, stylesFactory } from '@grafana/ui'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import config from 'app/core/config'; import { backendSrv } from 'app/core/services/backend_srv'; import { addQuery, queryIsEmpty } from 'app/core/utils/query'; import * as DFImport from 'app/features/dataframe-import'; +import { DataSourceModal } from 'app/features/datasources/components/picker/DataSourceModal'; import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker'; import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; import { DashboardQueryEditor, isSharedDashboardQuery } from 'app/plugins/datasource/dashboard'; @@ -51,6 +52,7 @@ interface State { isLoadingHelp: boolean; isPickerOpen: boolean; isAddingMixed: boolean; + isDataSourceModalOpen: boolean; data: PanelData; isHelpOpen: boolean; defaultDataSource?: DataSourceApi; @@ -69,6 +71,7 @@ export class QueryGroup extends PureComponent { querySubscription: Unsubscribable | null = null; state: State = { + isDataSourceModalOpen: false, isLoadingHelp: false, helpContent: null, isPickerOpen: false, @@ -116,6 +119,11 @@ export class QueryGroup extends PureComponent { dataSource: { ...options.dataSource }, savedQueryUid: options.savedQueryUid, }, + // TODO: Detect the first panel added into a new dashboard better. + // This is flaky in case the UID is generated differently + isDataSourceModalOpen: + locationService.getLocation().pathname === '/dashboard/new' && + locationService.getSearchObject().editPanel === '1', }); } catch (error) { console.log('failed to load data source', error); @@ -213,24 +221,7 @@ export class QueryGroup extends PureComponent { Data source -
- -
+
{this.renderDataSourcePickerWithPrompt()}
{dataSource && ( <>
@@ -290,6 +281,42 @@ export class QueryGroup extends PureComponent { ); }; + renderDataSourcePickerWithPrompt = () => { + const { isDataSourceModalOpen } = this.state; + + const commonProps = { + enableFileUpload: config.featureToggles.editPanelCSVDragAndDrop, + fileUploadOptions: { + onDrop: this.onFileDrop, + maxSize: DFImport.maxFileSize, + multiple: false, + accept: DFImport.acceptedFiles, + }, + current: this.props.options.dataSource, + onChange: (ds: DataSourceInstanceSettings) => { + this.onChangeDataSource(ds); + this.setState({ isDataSourceModalOpen: false }); + }, + }; + const onDismiss = () => this.setState({ isDataSourceModalOpen: false }); + + return ( + <> + {isDataSourceModalOpen && config.featureToggles.advancedDataSourcePicker && ( + + )} + + + ); + }; + onAddMixedQuery = (datasource: any) => { this.onAddQuery({ datasource: datasource.name }); this.setState({ isAddingMixed: false });