mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DirectInput: new alpha datasource that lets you enter data via CSV
Initial alpha datasource that saves data directly in a panel or in the shared datasource configs.
This commit is contained in:
@@ -12,14 +12,14 @@ TableInputStories.addDecorator(withCenteredStory);
|
||||
|
||||
TableInputStories.add('default', () => {
|
||||
return (
|
||||
<div style={{ width: '90%', height: '90vh' }}>
|
||||
<TableInputCSV
|
||||
text={'a,b,c\n1,2,3'}
|
||||
onSeriesParsed={(data: SeriesData[], text: string) => {
|
||||
console.log('Data', data, text);
|
||||
action('Data')(data, text);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<TableInputCSV
|
||||
width={400}
|
||||
height={'90vh'}
|
||||
text={'a,b,c\n1,2,3'}
|
||||
onSeriesParsed={(data: SeriesData[], text: string) => {
|
||||
console.log('Data', data, text);
|
||||
action('Data')(data, text);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -9,6 +9,8 @@ describe('TableInputCSV', () => {
|
||||
const tree = renderer
|
||||
.create(
|
||||
<TableInputCSV
|
||||
width={'100%'}
|
||||
height={200}
|
||||
text={'a,b,c\n1,2,3'}
|
||||
onSeriesParsed={(data: SeriesData[], text: string) => {
|
||||
// console.log('Table:', table, 'from:', text);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { SeriesData } from '../../types/data';
|
||||
import { AutoSizer } from 'react-virtualized';
|
||||
import { CSVConfig, readCSV } from '../../utils/csv';
|
||||
|
||||
interface Props {
|
||||
config?: CSVConfig;
|
||||
text: string;
|
||||
width: string | number;
|
||||
height: string | number;
|
||||
onSeriesParsed: (data: SeriesData[], text: string) => void;
|
||||
}
|
||||
|
||||
@@ -18,7 +19,7 @@ interface State {
|
||||
/**
|
||||
* Expects the container div to have size set and will fill it 100%
|
||||
*/
|
||||
class TableInputCSV extends React.PureComponent<Props, State> {
|
||||
export class TableInputCSV extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
@@ -58,28 +59,30 @@ class TableInputCSV extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { width, height } = this.props;
|
||||
const { data } = this.state;
|
||||
|
||||
return (
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<div className="gf-table-input-csv" style={{ width, height }}>
|
||||
<textarea placeholder="Enter CSV here..." value={this.state.text} onChange={this.onTextChange} />
|
||||
{data && (
|
||||
<footer>
|
||||
{data.map((series, index) => {
|
||||
return (
|
||||
<span key={index}>
|
||||
Rows:{series.rows.length}, Columns:{series.fields.length}
|
||||
<i className="fa fa-check-circle" />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</footer>
|
||||
)}
|
||||
</div>
|
||||
<div className="gf-table-input-csv">
|
||||
<textarea
|
||||
style={{ width, height }}
|
||||
placeholder="Enter CSV here..."
|
||||
value={this.state.text}
|
||||
onChange={this.onTextChange}
|
||||
className="gf-form-input"
|
||||
/>
|
||||
{data && (
|
||||
<footer>
|
||||
{data.map((series, index) => {
|
||||
return (
|
||||
<span key={index}>
|
||||
Rows:{series.rows.length}, Columns:{series.fields.length}
|
||||
<i className="fa fa-check-circle" />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</footer>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
.gf-table-input-csv textarea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.gf-table-input-csv footer {
|
||||
@@ -13,8 +12,7 @@
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
border: 1px solid #222;
|
||||
background: #ccc;
|
||||
background: $online;
|
||||
padding: 1px 4px;
|
||||
font-size: 80%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ export { UnitPicker } from './UnitPicker/UnitPicker';
|
||||
export { StatsPicker } from './StatsPicker/StatsPicker';
|
||||
export { Input, InputStatus } from './Input/Input';
|
||||
|
||||
export { Table } from './Table/Table';
|
||||
export { TableInputCSV } from './Table/TableInputCSV';
|
||||
|
||||
// Visualizations
|
||||
export { BigValue } from './BigValue/BigValue';
|
||||
export { Gauge } from './Gauge/Gauge';
|
||||
|
||||
@@ -116,6 +116,11 @@ export interface DataSourceApi<TQuery extends DataQuery = DataQuery> {
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Set after constructor is called by Grafana
|
||||
*/
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Set after constructor call, as the data source instance is the most common thing to pass around
|
||||
* we attach the components to this instance for easy access
|
||||
@@ -275,6 +280,7 @@ export interface DataSourceSettings {
|
||||
* as this data model is available to every user who has access to a data source (Viewers+).
|
||||
*/
|
||||
export interface DataSourceInstanceSettings {
|
||||
id: number;
|
||||
type: string;
|
||||
name: string;
|
||||
meta: PluginMeta;
|
||||
|
||||
@@ -316,6 +316,10 @@ function getHeaderLine(key: string, fields: Field[], config: CSVConfig): string
|
||||
}
|
||||
|
||||
export function toCSV(data: SeriesData[], config?: CSVConfig): string {
|
||||
if (!data) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let csv = '';
|
||||
config = defaults(config, {
|
||||
delimiter: ',',
|
||||
|
||||
Reference in New Issue
Block a user