Introduce MeasurementList to schema explorer
parent
7c40c417dc
commit
96ffc67d76
|
@ -1,7 +1,9 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import uuid from 'uuid'
|
||||
|
||||
import DatabaseListItem from 'src/ifql/components/DatabaseListItem'
|
||||
import MeasurementList from 'src/ifql/components/MeasurementList'
|
||||
|
||||
import {Source} from 'src/types'
|
||||
|
||||
|
@ -18,6 +20,7 @@ interface DatabaseListProps {
|
|||
|
||||
interface DatabaseListState {
|
||||
databases: string[]
|
||||
measurement: string
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -26,6 +29,7 @@ class DatabaseList extends PureComponent<DatabaseListProps, DatabaseListState> {
|
|||
super(props)
|
||||
this.state = {
|
||||
databases: [],
|
||||
measurement: '',
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,15 +43,7 @@ class DatabaseList extends PureComponent<DatabaseListProps, DatabaseListState> {
|
|||
try {
|
||||
const {data} = await showDatabases(source.links.proxy)
|
||||
const {databases} = showDatabasesParser(data)
|
||||
const dbs = databases.map(database => {
|
||||
if (database === '_internal') {
|
||||
return `${database}.monitor`
|
||||
}
|
||||
|
||||
return `${database}.autogen`
|
||||
})
|
||||
|
||||
const sorted = dbs.sort()
|
||||
const sorted = databases.sort()
|
||||
|
||||
this.setState({databases: sorted})
|
||||
const db = _.get(sorted, '0', '')
|
||||
|
@ -65,12 +61,21 @@ class DatabaseList extends PureComponent<DatabaseListProps, DatabaseListState> {
|
|||
<div className="query-builder--list">
|
||||
{this.state.databases.map(db => {
|
||||
return (
|
||||
<DatabaseListItem
|
||||
key={db}
|
||||
db={db}
|
||||
isActive={this.props.db === db}
|
||||
onChooseDatabase={onChooseDatabase}
|
||||
/>
|
||||
<>
|
||||
<DatabaseListItem
|
||||
key={uuid.v4()}
|
||||
db={db}
|
||||
isActive={this.props.db === db}
|
||||
onChooseDatabase={onChooseDatabase}
|
||||
/>
|
||||
{this.props.db === db && (
|
||||
<MeasurementList
|
||||
key={uuid.v4()}
|
||||
db={db}
|
||||
onChooseMeasurement={this.handleChooseMeasurement}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
|
|
@ -9,10 +9,19 @@ export interface Props {
|
|||
}
|
||||
|
||||
class DatabaseListItem extends PureComponent<Props> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
measurement: '',
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {db} = this.props
|
||||
|
||||
return (
|
||||
<div className={this.className} onClick={this.handleChooseDatabase}>
|
||||
{this.props.db}
|
||||
{db}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import {showMeasurements} from 'src/shared/apis/metaQuery'
|
||||
import showMeasurementsParser from 'src/shared/parsing/showMeasurements'
|
||||
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
import MeasurementListFilter from 'src/shared/components/MeasurementListFilter'
|
||||
import MeasurementListItem from 'src/shared/components/MeasurementListItem'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface Props {
|
||||
onChooseMeasurement: (measurement: string) => void
|
||||
db: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
measurements: string[]
|
||||
filterText: string
|
||||
filtered: string[]
|
||||
selected: string
|
||||
}
|
||||
|
||||
const {shape} = PropTypes
|
||||
|
||||
@ErrorHandling
|
||||
class MeasurementList extends PureComponent<Props, State> {
|
||||
public static contextTypes = {
|
||||
source: shape({
|
||||
links: shape({}).isRequired,
|
||||
}).isRequired,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
filterText: '',
|
||||
filtered: [],
|
||||
measurements: [],
|
||||
selected: '',
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
if (!this.props.db) {
|
||||
return
|
||||
}
|
||||
|
||||
this.getMeasurements()
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {filtered} = this.state
|
||||
|
||||
return (
|
||||
<div className="query-builder--column">
|
||||
<div className="query-builder--heading">
|
||||
<span>Measurements & Tags</span>
|
||||
<MeasurementListFilter
|
||||
onEscape={this.handleEscape}
|
||||
onFilterText={this.handleFilterText}
|
||||
filterText={this.state.filterText}
|
||||
/>
|
||||
</div>
|
||||
<div className="query-builder--list">
|
||||
{filtered.map(measurement => (
|
||||
<MeasurementListItem
|
||||
key={measurement}
|
||||
measurement={measurement}
|
||||
selected={this.state.selected}
|
||||
onChooseTag={this.handleChooseTag}
|
||||
onChooseMeasurement={this.handleChooseMeasurement}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleChooseTag = () => {
|
||||
console.log('Choose a tag')
|
||||
}
|
||||
|
||||
private async getMeasurements() {
|
||||
const {source} = this.context
|
||||
const {db} = this.props
|
||||
|
||||
try {
|
||||
const {data} = await showMeasurements(source.links.proxy, db)
|
||||
const {measurementSets} = showMeasurementsParser(data)
|
||||
const measurements = measurementSets[0].measurements
|
||||
|
||||
const selected = measurements[0]
|
||||
this.setState({measurements, filtered: measurements, selected})
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
private handleChooseMeasurement = (selected: string): void => {
|
||||
this.setState({selected})
|
||||
}
|
||||
|
||||
private handleFilterText = e => {
|
||||
e.stopPropagation()
|
||||
const filterText = e.target.value
|
||||
this.setState({
|
||||
filterText,
|
||||
filtered: this.handleFilterMeasuremet(filterText),
|
||||
})
|
||||
}
|
||||
|
||||
private handleFilterMeasuremet = filter => {
|
||||
return this.state.measurements.filter(m =>
|
||||
m.toLowerCase().includes(filter.toLowerCase())
|
||||
)
|
||||
}
|
||||
|
||||
private handleEscape = e => {
|
||||
if (e.key !== 'Escape') {
|
||||
return
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
this.setState({
|
||||
filterText: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default MeasurementList
|
|
@ -0,0 +1,56 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface Props {
|
||||
selected: string
|
||||
measurement: string
|
||||
onChooseTag: () => void
|
||||
onChooseMeasurement: (measurement: string) => void
|
||||
}
|
||||
|
||||
interface State {
|
||||
isOpen: boolean
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class MeasurementListItem extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {isOpen: this.isCurrentMeasurement}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {measurement} = this.props
|
||||
|
||||
return (
|
||||
<div key={measurement} onClick={this.handleClick}>
|
||||
<div className="query-builder--list-item">
|
||||
<span>
|
||||
<div className="query-builder--caret icon caret-right" />
|
||||
{measurement}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleClick = () => {
|
||||
const {measurement, onChooseMeasurement} = this.props
|
||||
|
||||
if (!this.isCurrentMeasurement) {
|
||||
this.setState({isOpen: true}, () => {
|
||||
onChooseMeasurement(measurement)
|
||||
})
|
||||
} else {
|
||||
this.setState({isOpen: !this.state.isOpen})
|
||||
}
|
||||
}
|
||||
|
||||
private get isCurrentMeasurement(): boolean {
|
||||
const {selected, measurement} = this.props
|
||||
return selected === measurement
|
||||
}
|
||||
}
|
||||
|
||||
export default MeasurementListItem
|
Loading…
Reference in New Issue