mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Add a wrapper to switch between the previous and new DS picker depending on the feature toggle advancedDataSourcePicker. * Add a new component to represent the modal DS picker, which we will refer as advanced DS picker Integrate this into the Edit panel, for now, until we're ready to replace everywhere the grafana-runtime DS picker by the wrapper. * Replace Drawer component with the dropdown * Adjust the first version of the styles to fit into this Figma design * Adjust the design of the FileDropzoneDefaultChildren to match with the new DS modal but everywhere else is used nowadays. --------- Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com>
161 lines
4.3 KiB
TypeScript
161 lines
4.3 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useState } from 'react';
|
|
import { DropzoneOptions } from 'react-dropzone';
|
|
|
|
import { DataSourceInstanceSettings, DataSourceRef, GrafanaTheme2 } from '@grafana/data';
|
|
import {
|
|
Modal,
|
|
FileDropzone,
|
|
FileDropzoneDefaultChildren,
|
|
CustomScrollbar,
|
|
LinkButton,
|
|
useStyles2,
|
|
Input,
|
|
Icon,
|
|
} from '@grafana/ui';
|
|
import * as DFImport from 'app/features/dataframe-import';
|
|
|
|
import { DataSourceList } from './DataSourceList';
|
|
|
|
interface DataSourceModalProps {
|
|
onChange: (ds: DataSourceInstanceSettings) => void;
|
|
current: DataSourceRef | string | null | undefined;
|
|
onDismiss: () => void;
|
|
datasources: DataSourceInstanceSettings[];
|
|
recentlyUsed?: string[];
|
|
enableFileUpload?: boolean;
|
|
fileUploadOptions?: DropzoneOptions;
|
|
}
|
|
|
|
export function DataSourceModal({
|
|
enableFileUpload,
|
|
fileUploadOptions,
|
|
onChange,
|
|
current,
|
|
onDismiss,
|
|
}: DataSourceModalProps) {
|
|
const styles = useStyles2(getDataSourceModalStyles);
|
|
const [search, setSearch] = useState('');
|
|
|
|
return (
|
|
<Modal
|
|
title="Select data source"
|
|
closeOnEscape={true}
|
|
closeOnBackdropClick={true}
|
|
isOpen={true}
|
|
className={styles.modal}
|
|
onClickBackdrop={onDismiss}
|
|
onDismiss={onDismiss}
|
|
>
|
|
<div className={styles.modalContent}>
|
|
<div className={styles.leftColumn}>
|
|
<Input
|
|
className={styles.searchInput}
|
|
value={search}
|
|
prefix={<Icon name="search" />}
|
|
placeholder="Search data source"
|
|
onChange={(e) => setSearch(e.currentTarget.value)}
|
|
/>
|
|
<CustomScrollbar>
|
|
<DataSourceList
|
|
dashboard={false}
|
|
mixed={false}
|
|
// FIXME: Filter out the grafana data source in a hacky way
|
|
filter={(ds) => ds.name.includes(search) && ds.name !== '-- Grafana --'}
|
|
onChange={onChange}
|
|
current={current}
|
|
/>
|
|
</CustomScrollbar>
|
|
</div>
|
|
<div className={styles.rightColumn}>
|
|
<div className={styles.builtInDataSources}>
|
|
<DataSourceList
|
|
className={styles.builtInDataSourceList}
|
|
filter={(ds) => !!ds.meta.builtIn}
|
|
dashboard
|
|
mixed
|
|
onChange={onChange}
|
|
current={current}
|
|
/>
|
|
{enableFileUpload && (
|
|
<FileDropzone
|
|
readAs="readAsArrayBuffer"
|
|
fileListRenderer={() => undefined}
|
|
options={{
|
|
maxSize: DFImport.maxFileSize,
|
|
multiple: false,
|
|
accept: DFImport.acceptedFiles,
|
|
...fileUploadOptions,
|
|
onDrop: (...args) => {
|
|
fileUploadOptions?.onDrop?.(...args);
|
|
onDismiss();
|
|
},
|
|
}}
|
|
>
|
|
<FileDropzoneDefaultChildren />
|
|
</FileDropzone>
|
|
)}
|
|
</div>
|
|
<div className={styles.dsCTAs}>
|
|
<LinkButton variant="secondary" href={`datasources/new`}>
|
|
Configure a new data source
|
|
</LinkButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
function getDataSourceModalStyles(theme: GrafanaTheme2) {
|
|
return {
|
|
modal: css`
|
|
width: 80%;
|
|
height: 80%;
|
|
`,
|
|
modalContent: css`
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
align-items: stretch;
|
|
height: 100%;
|
|
`,
|
|
leftColumn: css`
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 50%;
|
|
height: 100%;
|
|
padding-right: ${theme.spacing(1)};
|
|
border-right: 1px solid ${theme.colors.border.weak};
|
|
`,
|
|
rightColumn: css`
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 50%;
|
|
height: 100%;
|
|
padding: ${theme.spacing(1)};
|
|
justify-items: space-evenly;
|
|
align-items: stretch;
|
|
padding-left: ${theme.spacing(1)};
|
|
`,
|
|
builtInDataSources: css`
|
|
flex: 1;
|
|
margin-bottom: ${theme.spacing(4)};
|
|
`,
|
|
builtInDataSourceList: css`
|
|
margin-bottom: ${theme.spacing(4)};
|
|
`,
|
|
dsCTAs: css`
|
|
display: flex;
|
|
flex-direction: row;
|
|
width: 100%;
|
|
justify-content: flex-end;
|
|
`,
|
|
searchInput: css`
|
|
width: 100%;
|
|
min-height: 32px;
|
|
margin-bottom: ${theme.spacing(1)};
|
|
`,
|
|
};
|
|
}
|