commit
4cb8a0632b
|
@ -78,7 +78,7 @@ export const getBuckets = () => async (
|
||||||
orgs: {org},
|
orgs: {org},
|
||||||
} = getState()
|
} = getState()
|
||||||
|
|
||||||
const buckets = (await client.buckets.getAll(org.id)) as Bucket[]
|
const buckets = await client.buckets.getAll(org.id)
|
||||||
|
|
||||||
dispatch(setBuckets(RemoteDataState.Done, buckets))
|
dispatch(setBuckets(RemoteDataState.Done, buckets))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import _ from 'lodash'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {IndexList, ConfirmationButton, Context} from 'src/clockface'
|
import {IndexList, ConfirmationButton, Context} from 'src/clockface'
|
||||||
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
|
|
||||||
import EditableName from 'src/shared/components/EditableName'
|
import EditableName from 'src/shared/components/EditableName'
|
||||||
|
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {DEFAULT_BUCKET_NAME} from 'src/dashboards/constants'
|
import {DEFAULT_BUCKET_NAME} from 'src/dashboards/constants'
|
||||||
|
@ -77,13 +77,13 @@ class BucketRow extends PureComponent<Props & WithRouterProps> {
|
||||||
description="Quickly load an existing line protocol file."
|
description="Quickly load an existing line protocol file."
|
||||||
action={this.handleAddLineProtocol}
|
action={this.handleAddLineProtocol}
|
||||||
/>
|
/>
|
||||||
<CloudFeatureFlag>
|
<CloudExclude>
|
||||||
<Context.Item
|
<Context.Item
|
||||||
label="Scrape Metrics"
|
label="Scrape Metrics"
|
||||||
description="Add a scrape target to pull data into your bucket."
|
description="Add a scrape target to pull data into your bucket."
|
||||||
action={this.handleAddScraper}
|
action={this.handleAddScraper}
|
||||||
/>
|
/>
|
||||||
</CloudFeatureFlag>
|
</CloudExclude>
|
||||||
</Context.Menu>
|
</Context.Menu>
|
||||||
</Context>
|
</Context>
|
||||||
</IndexList.Cell>
|
</IndexList.Cell>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import _ from 'lodash'
|
||||||
// Components
|
// Components
|
||||||
import Table from 'src/dashboards/components/dashboard_index/Table'
|
import Table from 'src/dashboards/components/dashboard_index/Table'
|
||||||
import FilterList from 'src/shared/components/Filter'
|
import FilterList from 'src/shared/components/Filter'
|
||||||
import GetLabels from 'src/labels/components/GetLabels'
|
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
@ -43,7 +43,7 @@ export default class DashboardsIndexContents extends Component<Props> {
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GetLabels>
|
<GetResources resource={ResourceTypes.Labels}>
|
||||||
<FilterList<Dashboard>
|
<FilterList<Dashboard>
|
||||||
list={dashboards}
|
list={dashboards}
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
|
@ -64,7 +64,7 @@ export default class DashboardsIndexContents extends Component<Props> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FilterList>
|
</FilterList>
|
||||||
</GetLabels>
|
</GetResources>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
// TODO make recursive
|
|
||||||
const exprStr = ({expr, val, type}) => {
|
|
||||||
if (expr === 'reference') {
|
|
||||||
if (val === 'time') {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
return `"${val}"`
|
|
||||||
} else if (expr === 'literal' || expr === '"string"') {
|
|
||||||
if (type === 'regex') {
|
|
||||||
return `${val}` // TODO add slashes `/${val}/`
|
|
||||||
} else if (type === 'list') {
|
|
||||||
throw new Error() // TODO list
|
|
||||||
} else if (type === 'string') {
|
|
||||||
return `'${val}'`
|
|
||||||
} else {
|
|
||||||
// types: boolean, number, integer, duration, time
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
} else if (expr === 'wildcard') {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const recurse = root => {
|
|
||||||
const {expr} = root
|
|
||||||
|
|
||||||
if (expr === 'binary') {
|
|
||||||
const {op, lhs, rhs} = root
|
|
||||||
return `${recurse(lhs)} ${op} ${recurse(rhs)}`
|
|
||||||
} else if (expr === 'call') {
|
|
||||||
const {name, args} = root
|
|
||||||
if (!args) {
|
|
||||||
return `${name}()`
|
|
||||||
}
|
|
||||||
return `${name}(${args.map(recurse).join(', ')})`
|
|
||||||
}
|
|
||||||
|
|
||||||
return exprStr(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const toString = ast => {
|
|
||||||
const {fields, sources, condition, groupBy, orderbys, limits} = ast
|
|
||||||
|
|
||||||
const strs = ['SELECT']
|
|
||||||
|
|
||||||
// SELECT
|
|
||||||
const flds = []
|
|
||||||
for (const field of fields) {
|
|
||||||
const {column, alias} = field
|
|
||||||
const result = recurse(column)
|
|
||||||
flds.push(alias ? `${result} AS "${alias}"` : result)
|
|
||||||
}
|
|
||||||
strs.push(flds.join(', '))
|
|
||||||
|
|
||||||
// FROM
|
|
||||||
if (sources.length) {
|
|
||||||
strs.push('FROM')
|
|
||||||
const srcs = []
|
|
||||||
for (const source of sources) {
|
|
||||||
// TODO subquery (type)
|
|
||||||
const {database, retentionPolicy, name} = source
|
|
||||||
srcs.push(`"${_.compact([database, retentionPolicy, name]).join('"."')}"`)
|
|
||||||
}
|
|
||||||
strs.push(srcs.join(', '))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WHERE
|
|
||||||
if (condition) {
|
|
||||||
strs.push('WHERE')
|
|
||||||
const result = recurse(condition)
|
|
||||||
strs.push(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GROUP BY
|
|
||||||
if (groupBy) {
|
|
||||||
strs.push('GROUP BY')
|
|
||||||
|
|
||||||
const dimensions = []
|
|
||||||
const {time, tags, fill} = groupBy
|
|
||||||
if (time) {
|
|
||||||
const {interval, offset} = time
|
|
||||||
// _.compact([interval, offset]).join(', ')
|
|
||||||
dimensions.push(`time(${_.compact([interval, offset]).join(', ')})`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags) {
|
|
||||||
strs.push(dimensions.concat(tags).join(','))
|
|
||||||
} else {
|
|
||||||
strs.push(dimensions.join(','))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fill) {
|
|
||||||
strs.push(`fill(${fill})`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ORDER BY
|
|
||||||
if (orderbys && orderbys.length) {
|
|
||||||
strs.push('ORDER BY')
|
|
||||||
strs.push(
|
|
||||||
orderbys
|
|
||||||
.map(({name, order}) => {
|
|
||||||
return `${name} ${order === 'descending' ? 'DESC' : 'ASC'}`
|
|
||||||
})
|
|
||||||
.join(',')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LIMIT
|
|
||||||
if (limits) {
|
|
||||||
const {limit, offset, slimit, soffset} = limits
|
|
||||||
if (limit) {
|
|
||||||
strs.push(`LIMIT ${limit}`)
|
|
||||||
}
|
|
||||||
if (offset) {
|
|
||||||
strs.push(`OFFSET ${offset}`)
|
|
||||||
}
|
|
||||||
if (slimit) {
|
|
||||||
strs.push(`SLIMIT ${slimit}`)
|
|
||||||
}
|
|
||||||
if (soffset) {
|
|
||||||
strs.push(`SOFFSET ${soffset}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strs.join(' ')
|
|
||||||
}
|
|
|
@ -1,406 +0,0 @@
|
||||||
import InfluxQL from 'src/influxql'
|
|
||||||
|
|
||||||
describe('influxql astToString', () => {
|
|
||||||
it('simple query', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '+',
|
|
||||||
lhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '1',
|
|
||||||
type: 'integer',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'A',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'howdy',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected = `SELECT 1 + "A" FROM "howdy"`
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
// console.log(actual)
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('simple query w/ multiple sources', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '+',
|
|
||||||
lhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '1',
|
|
||||||
type: 'integer',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'A',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'howdy',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
database: 'telegraf',
|
|
||||||
retentionPolicy: 'autogen',
|
|
||||||
name: 'doody',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected = `SELECT 1 + "A" FROM "howdy", "telegraf"."autogen"."doody"`
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
// console.log('actual ', actual)
|
|
||||||
// console.log('expected', expected)
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('query with AS', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
alias: 'B',
|
|
||||||
column: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '+',
|
|
||||||
lhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '1',
|
|
||||||
type: 'integer',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'A',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'howdy',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected = `SELECT 1 + "A" AS "B" FROM "howdy"`
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
// console.log(actual)
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('query with 2x func', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '/',
|
|
||||||
lhs: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'derivative',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'field1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expr: 'literal',
|
|
||||||
val: '1h',
|
|
||||||
type: 'duration',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'derivative',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'field2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expr: 'literal',
|
|
||||||
val: '1h',
|
|
||||||
type: 'duration',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'myseries',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected = `SELECT derivative("field1", 1h) / derivative("field2", 1h) FROM "myseries"`
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('query with where and groupby', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
condition: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: 'AND',
|
|
||||||
lhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: 'AND',
|
|
||||||
lhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '=~',
|
|
||||||
lhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'cluster_id',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '/^23/',
|
|
||||||
type: 'regex',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '=',
|
|
||||||
lhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'host',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: 'prod-2ccccc04-us-east-1-data-3',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '\u003e',
|
|
||||||
lhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'time',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '-',
|
|
||||||
lhs: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'now',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '15m',
|
|
||||||
type: 'duration',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
alias: 'max_cpus',
|
|
||||||
column: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'max',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'n_cpus',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'non_negative_derivative',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'call',
|
|
||||||
name: 'median',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'n_users',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expr: 'literal',
|
|
||||||
val: '5m',
|
|
||||||
type: 'duration',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
groupBy: {
|
|
||||||
time: {
|
|
||||||
interval: '15m',
|
|
||||||
offset: '10s',
|
|
||||||
},
|
|
||||||
tags: ['host', 'tag_x'],
|
|
||||||
fill: '10',
|
|
||||||
},
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'system',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected =
|
|
||||||
'SELECT max("n_cpus") AS "max_cpus", non_negative_derivative(median("n_users"), 5m) FROM "system" WHERE "cluster_id" =~ /^23/ AND "host" = \'prod-2ccccc04-us-east-1-data-3\' AND time > now() - 15m GROUP BY time(15m, 10s),host,tag_x fill(10)'
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
// console.log('actual ', actual)
|
|
||||||
// console.log('expected', expected)
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('query with orderby and limit', () => {
|
|
||||||
const ast = InfluxQL({
|
|
||||||
condition: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: 'AND',
|
|
||||||
lhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '=',
|
|
||||||
lhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'host',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: 'hosta.influxdb.org',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'binary',
|
|
||||||
op: '\u003e',
|
|
||||||
lhs: {
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'time',
|
|
||||||
},
|
|
||||||
rhs: {
|
|
||||||
expr: 'literal',
|
|
||||||
val: '2017-02-07T01:43:02.245407693Z',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'mean',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'field1',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'sum',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'field2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
alias: 'field_x',
|
|
||||||
column: {
|
|
||||||
expr: 'call',
|
|
||||||
name: 'count',
|
|
||||||
args: [
|
|
||||||
{
|
|
||||||
expr: 'reference',
|
|
||||||
val: 'field3',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
groupBy: {
|
|
||||||
time: {
|
|
||||||
interval: '10h',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
limits: {
|
|
||||||
limit: 20,
|
|
||||||
offset: 10,
|
|
||||||
},
|
|
||||||
orderbys: [
|
|
||||||
{
|
|
||||||
name: 'time',
|
|
||||||
order: 'descending',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
database: '',
|
|
||||||
retentionPolicy: '',
|
|
||||||
name: 'myseries',
|
|
||||||
type: 'measurement',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
const expected = `SELECT mean("field1"), sum("field2"), count("field3") AS "field_x" FROM "myseries" WHERE "host" = 'hosta.influxdb.org' AND time > '2017-02-07T01:43:02.245407693Z' GROUP BY time(10h) ORDER BY time DESC LIMIT 20 OFFSET 10`
|
|
||||||
const actual = ast.toString()
|
|
||||||
|
|
||||||
// console.log('actual ', actual)
|
|
||||||
// console.log('expected', expected)
|
|
||||||
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,9 +0,0 @@
|
||||||
import {toString} from './ast'
|
|
||||||
|
|
||||||
const InfluxQL = ast => {
|
|
||||||
return {
|
|
||||||
toString: () => toString(ast),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default InfluxQL
|
|
|
@ -73,13 +73,11 @@ export const getLabels = () => async (
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
orgs: {
|
orgs: {org},
|
||||||
org: {id},
|
|
||||||
},
|
|
||||||
} = getState()
|
} = getState()
|
||||||
dispatch(setLabels(RemoteDataState.Loading))
|
dispatch(setLabels(RemoteDataState.Loading))
|
||||||
|
|
||||||
const labels = await client.labels.getAll(id)
|
const labels = await client.labels.getAll(org.id)
|
||||||
|
|
||||||
dispatch(setLabels(RemoteDataState.Done, labels))
|
dispatch(setLabels(RemoteDataState.Done, labels))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
// Libraries
|
|
||||||
import React, {PureComponent} from 'react'
|
|
||||||
import _ from 'lodash'
|
|
||||||
import {connect} from 'react-redux'
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
import {getLabels} from 'src/labels/actions'
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import {RemoteDataState} from 'src/types'
|
|
||||||
import {AppState} from 'src/types'
|
|
||||||
|
|
||||||
// Decorators
|
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
|
||||||
import {TechnoSpinner} from '@influxdata/clockface'
|
|
||||||
|
|
||||||
interface StateProps {
|
|
||||||
status: RemoteDataState
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DispatchProps {
|
|
||||||
getLabels: typeof getLabels
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = StateProps & DispatchProps
|
|
||||||
|
|
||||||
@ErrorHandling
|
|
||||||
class GetLabels extends PureComponent<Props, StateProps> {
|
|
||||||
public async componentDidMount() {
|
|
||||||
await this.props.getLabels()
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const {status, children} = this.props
|
|
||||||
|
|
||||||
if (status != RemoteDataState.Done) {
|
|
||||||
return <TechnoSpinner />
|
|
||||||
}
|
|
||||||
|
|
||||||
return children
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mstp = ({labels}: AppState): StateProps => {
|
|
||||||
return {
|
|
||||||
status: labels.status,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mdtp = {
|
|
||||||
getLabels: getLabels,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect<StateProps, DispatchProps, {}>(
|
|
||||||
mstp,
|
|
||||||
mdtp
|
|
||||||
)(GetLabels)
|
|
|
@ -5,8 +5,8 @@ import {Link} from 'react-router'
|
||||||
// Components
|
// Components
|
||||||
import {NavMenu} from '@influxdata/clockface'
|
import {NavMenu} from '@influxdata/clockface'
|
||||||
import {Organization} from '@influxdata/influx'
|
import {Organization} from '@influxdata/influx'
|
||||||
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
|
|
||||||
import SortingHat from 'src/shared/components/sorting_hat/SortingHat'
|
import SortingHat from 'src/shared/components/sorting_hat/SortingHat'
|
||||||
|
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
orgs: Organization[]
|
orgs: Organization[]
|
||||||
|
@ -29,7 +29,7 @@ class AccountNavSubItem extends PureComponent<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CloudFeatureFlag key="feature-flag">
|
<CloudExclude key="feature-flag">
|
||||||
{orgs.length > 1 && (
|
{orgs.length > 1 && (
|
||||||
<NavMenu.SubItem
|
<NavMenu.SubItem
|
||||||
titleLink={className => (
|
titleLink={className => (
|
||||||
|
@ -50,7 +50,7 @@ class AccountNavSubItem extends PureComponent<Props> {
|
||||||
)}
|
)}
|
||||||
active={false}
|
active={false}
|
||||||
/>
|
/>
|
||||||
</CloudFeatureFlag>
|
</CloudExclude>
|
||||||
|
|
||||||
<NavMenu.SubItem
|
<NavMenu.SubItem
|
||||||
titleLink={className => (
|
titleLink={className => (
|
||||||
|
|
|
@ -76,13 +76,12 @@ export const getScrapers = () => async (
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
orgs: {
|
orgs: {org},
|
||||||
org: {id},
|
|
||||||
},
|
|
||||||
} = getState()
|
} = getState()
|
||||||
|
|
||||||
dispatch(setScrapers(RemoteDataState.Loading))
|
dispatch(setScrapers(RemoteDataState.Loading))
|
||||||
|
|
||||||
const scrapers = await client.scrapers.getAll(id)
|
const scrapers = await client.scrapers.getAll(org.id)
|
||||||
|
|
||||||
dispatch(setScrapers(RemoteDataState.Done, scrapers))
|
dispatch(setScrapers(RemoteDataState.Done, scrapers))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {Tabs} from 'src/clockface'
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
|
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tab: string
|
tab: string
|
||||||
|
@ -41,14 +41,14 @@ class SettingsNavigation extends PureComponent<Props> {
|
||||||
url={`${route}/telegrafs`}
|
url={`${route}/telegrafs`}
|
||||||
active={'telegrafs' === tab}
|
active={'telegrafs' === tab}
|
||||||
/>
|
/>
|
||||||
<CloudFeatureFlag>
|
<CloudExclude>
|
||||||
<Tabs.Tab
|
<Tabs.Tab
|
||||||
title="Scrapers"
|
title="Scrapers"
|
||||||
id="scrapers"
|
id="scrapers"
|
||||||
url={`${route}/scrapers`}
|
url={`${route}/scrapers`}
|
||||||
active={'scrapers' === tab}
|
active={'scrapers' === tab}
|
||||||
/>
|
/>
|
||||||
</CloudFeatureFlag>
|
</CloudExclude>
|
||||||
<Tabs.Tab
|
<Tabs.Tab
|
||||||
title="Variables"
|
title="Variables"
|
||||||
id="variables"
|
id="variables"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {MeState} from 'src/shared/reducers/v2/me'
|
import {MeState} from 'src/shared/reducers/me'
|
||||||
import {client} from 'src/utils/api'
|
import {client} from 'src/utils/api'
|
||||||
|
|
||||||
export enum ActionTypes {
|
export enum ActionTypes {
|
|
@ -1,23 +0,0 @@
|
||||||
// Libraries
|
|
||||||
import {PureComponent} from 'react'
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
import {CLOUD} from 'src/shared/constants'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
name?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class extends PureComponent<Props> {
|
|
||||||
public render() {
|
|
||||||
if (this.isHidden) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.props.children
|
|
||||||
}
|
|
||||||
|
|
||||||
private get isHidden(): boolean {
|
|
||||||
return CLOUD
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
// Libraries
|
|
||||||
import React, {PureComponent} from 'react'
|
|
||||||
import {withRouter, WithRouterProps} from 'react-router'
|
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
// Components
|
|
||||||
import {
|
|
||||||
EmptyState,
|
|
||||||
TechnoSpinner,
|
|
||||||
SpinnerContainer,
|
|
||||||
} from '@influxdata/clockface'
|
|
||||||
|
|
||||||
// APIs
|
|
||||||
import {client} from 'src/utils/api'
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import {RemoteDataState} from 'src/types'
|
|
||||||
import {Label} from 'src/types/labels'
|
|
||||||
|
|
||||||
// Decorators
|
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
|
||||||
|
|
||||||
interface PassedInProps {
|
|
||||||
children: (labels: Label[]) => JSX.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RouterProps extends WithRouterProps {
|
|
||||||
params: {
|
|
||||||
orgID: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = PassedInProps & RouterProps
|
|
||||||
|
|
||||||
interface State {
|
|
||||||
labels: Label[]
|
|
||||||
loading: RemoteDataState
|
|
||||||
}
|
|
||||||
|
|
||||||
@ErrorHandling
|
|
||||||
class FetchLabels extends PureComponent<Props, State> {
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
labels: [],
|
|
||||||
loading: RemoteDataState.NotStarted,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async componentDidMount() {
|
|
||||||
const {
|
|
||||||
params: {orgID},
|
|
||||||
} = this.props
|
|
||||||
const labels = await client.labels.getAll(orgID)
|
|
||||||
this.setState({
|
|
||||||
loading: RemoteDataState.Done,
|
|
||||||
labels: _.orderBy(labels, ['name']),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const {loading} = this.state
|
|
||||||
|
|
||||||
if (loading === RemoteDataState.Error) {
|
|
||||||
return (
|
|
||||||
<EmptyState>
|
|
||||||
<EmptyState.Text text="Could not load labels" />
|
|
||||||
</EmptyState>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SpinnerContainer loading={loading} spinnerComponent={<TechnoSpinner />}>
|
|
||||||
{this.props.children(this.state.labels)}
|
|
||||||
</SpinnerContainer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withRouter<PassedInProps>(FetchLabels)
|
|
|
@ -1,86 +0,0 @@
|
||||||
import {shallow} from 'enzyme'
|
|
||||||
import React from 'react'
|
|
||||||
import SubSections from 'src/shared/components/SubSections'
|
|
||||||
import SubSectionsTab from 'src/shared/components/SubSectionsTab'
|
|
||||||
|
|
||||||
const Guava = () => {
|
|
||||||
return <div />
|
|
||||||
}
|
|
||||||
|
|
||||||
const Mango = () => {
|
|
||||||
return <div />
|
|
||||||
}
|
|
||||||
|
|
||||||
const Pineapple = () => {
|
|
||||||
return <div />
|
|
||||||
}
|
|
||||||
|
|
||||||
const guavaURL = 'guava'
|
|
||||||
const mangoURL = 'mango'
|
|
||||||
const pineappleURL = 'pineapple'
|
|
||||||
|
|
||||||
const defaultProps = {
|
|
||||||
router: {
|
|
||||||
push: () => {},
|
|
||||||
replace: () => {},
|
|
||||||
go: () => {},
|
|
||||||
goBack: () => {},
|
|
||||||
goForward: () => {},
|
|
||||||
setRouteLeaveHook: () => {},
|
|
||||||
isActive: () => {},
|
|
||||||
},
|
|
||||||
sourceID: 'fruitstand',
|
|
||||||
parentUrl: 'fred-the-fruit-guy',
|
|
||||||
activeSection: guavaURL,
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
url: guavaURL,
|
|
||||||
name: 'Guava',
|
|
||||||
component: <Guava />,
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: mangoURL,
|
|
||||||
name: 'Mango',
|
|
||||||
component: <Mango />,
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: pineappleURL,
|
|
||||||
name: 'Pineapple',
|
|
||||||
component: <Pineapple />,
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
const setup = (override?: {}) => {
|
|
||||||
const props = {
|
|
||||||
...defaultProps,
|
|
||||||
...override,
|
|
||||||
}
|
|
||||||
|
|
||||||
return shallow(<SubSections {...props} />)
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('SubSections', () => {
|
|
||||||
describe('render', () => {
|
|
||||||
it('renders the currently active tab', () => {
|
|
||||||
const wrapper = setup()
|
|
||||||
const content = wrapper.dive().find({'data-testid': 'subsectionContent'})
|
|
||||||
|
|
||||||
expect(content.find(Guava).exists()).toBe(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('only renders enabled tabs', () => {
|
|
||||||
const wrapper = setup()
|
|
||||||
const nav = wrapper.dive().find({'data-testid': 'subsectionNav'})
|
|
||||||
|
|
||||||
const tabs = nav.find(SubSectionsTab)
|
|
||||||
|
|
||||||
tabs.forEach(tab => {
|
|
||||||
expect(tab.exists()).toBe(tab.props().section.enabled)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,65 +0,0 @@
|
||||||
import React, {Component, ReactNode} from 'react'
|
|
||||||
import uuid from 'uuid'
|
|
||||||
import {withRouter, InjectedRouter} from 'react-router'
|
|
||||||
|
|
||||||
import SubSectionsTab from 'src/shared/components/SubSectionsTab'
|
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
|
||||||
import {PageSection} from 'src/types/shared'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
sections: PageSection[]
|
|
||||||
activeSection: string
|
|
||||||
sourceID: string
|
|
||||||
router: InjectedRouter
|
|
||||||
parentUrl: string
|
|
||||||
}
|
|
||||||
|
|
||||||
@ErrorHandling
|
|
||||||
class SubSections extends Component<Props> {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const {sections, activeSection} = this.props
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="row subsection">
|
|
||||||
<div className="col-md-2 subsection--nav" data-testid="subsectionNav">
|
|
||||||
<div className="subsection--tabs">
|
|
||||||
{sections.map(
|
|
||||||
section =>
|
|
||||||
section.enabled && (
|
|
||||||
<SubSectionsTab
|
|
||||||
key={uuid.v4()}
|
|
||||||
section={section}
|
|
||||||
handleClick={this.handleTabClick(section.url)}
|
|
||||||
activeSection={activeSection}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="col-md-10 subsection--content"
|
|
||||||
data-testid="subsectionContent"
|
|
||||||
>
|
|
||||||
{this.activeSectionComponent}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private get activeSectionComponent(): ReactNode {
|
|
||||||
const {sections, activeSection} = this.props
|
|
||||||
const {component} = sections.find(section => section.url === activeSection)
|
|
||||||
return component
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleTabClick = url => () => {
|
|
||||||
const {router, sourceID, parentUrl} = this.props
|
|
||||||
router.push(`/sources/${sourceID}/${parentUrl}/${url}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withRouter(SubSections)
|
|
|
@ -1,25 +0,0 @@
|
||||||
import React, {SFC} from 'react'
|
|
||||||
import {PageSection} from 'src/types/shared'
|
|
||||||
|
|
||||||
interface TabProps {
|
|
||||||
handleClick: () => void
|
|
||||||
section: PageSection
|
|
||||||
activeSection: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const SubSectionsTab: SFC<TabProps> = ({
|
|
||||||
handleClick,
|
|
||||||
section,
|
|
||||||
activeSection,
|
|
||||||
}) => (
|
|
||||||
<div
|
|
||||||
className={`subsection--tab ${
|
|
||||||
section.url === activeSection ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={handleClick}
|
|
||||||
>
|
|
||||||
{section.name}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default SubSectionsTab
|
|
|
@ -9,7 +9,7 @@ import {SpinnerContainer, TechnoSpinner} from '@influxdata/clockface'
|
||||||
import {RemoteDataState} from 'src/types'
|
import {RemoteDataState} from 'src/types'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {getMe} from 'src/shared/actions/v2/me'
|
import {getMe} from 'src/shared/actions/me'
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Actions, ActionTypes} from 'src/shared/actions/v2/me'
|
import {Actions, ActionTypes} from 'src/shared/actions/me'
|
||||||
|
|
||||||
export interface MeLinks {
|
export interface MeLinks {
|
||||||
self: string
|
self: string
|
|
@ -10,7 +10,7 @@ import sharedReducers from 'src/shared/reducers'
|
||||||
import persistStateEnhancer from './persistStateEnhancer'
|
import persistStateEnhancer from './persistStateEnhancer'
|
||||||
|
|
||||||
// v2 reducers
|
// v2 reducers
|
||||||
import meReducer from 'src/shared/reducers/v2/me'
|
import meReducer from 'src/shared/reducers/me'
|
||||||
import tasksReducer from 'src/tasks/reducers'
|
import tasksReducer from 'src/tasks/reducers'
|
||||||
import rangesReducer from 'src/dashboards/reducers/ranges'
|
import rangesReducer from 'src/dashboards/reducers/ranges'
|
||||||
import {dashboardsReducer} from 'src/dashboards/reducers/dashboards'
|
import {dashboardsReducer} from 'src/dashboards/reducers/dashboards'
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {Page} from 'src/pageLayout'
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import FilterList from 'src/shared/components/Filter'
|
import FilterList from 'src/shared/components/Filter'
|
||||||
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
|
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
|
||||||
import GetLabels from 'src/labels/components/GetLabels'
|
|
||||||
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
@ -106,7 +105,7 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
<Page.Contents fullWidth={false} scrollable={true}>
|
<Page.Contents fullWidth={false} scrollable={true}>
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<GetResources resource={ResourceTypes.Tasks}>
|
<GetResources resource={ResourceTypes.Tasks}>
|
||||||
<GetLabels>
|
<GetResources resource={ResourceTypes.Labels}>
|
||||||
<FilterList<Task>
|
<FilterList<Task>
|
||||||
list={this.filteredTasks}
|
list={this.filteredTasks}
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
|
@ -133,7 +132,7 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
)}
|
)}
|
||||||
</FilterList>
|
</FilterList>
|
||||||
{this.hiddenTaskAlert}
|
{this.hiddenTaskAlert}
|
||||||
</GetLabels>
|
</GetResources>
|
||||||
</GetResources>
|
</GetResources>
|
||||||
</div>
|
</div>
|
||||||
</Page.Contents>
|
</Page.Contents>
|
||||||
|
|
|
@ -11,7 +11,7 @@ import CollectorList from 'src/telegrafs/components/CollectorList'
|
||||||
import TelegrafExplainer from 'src/telegrafs/components/TelegrafExplainer'
|
import TelegrafExplainer from 'src/telegrafs/components/TelegrafExplainer'
|
||||||
import FilterList from 'src/shared/components/Filter'
|
import FilterList from 'src/shared/components/Filter'
|
||||||
import NoBucketsWarning from 'src/buckets/components/NoBucketsWarning'
|
import NoBucketsWarning from 'src/buckets/components/NoBucketsWarning'
|
||||||
import GetLabels from 'src/labels/components/GetLabels'
|
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {setBucketInfo} from 'src/dataLoaders/actions/steps'
|
import {setBucketInfo} from 'src/dataLoaders/actions/steps'
|
||||||
|
@ -102,7 +102,7 @@ class Collectors extends PureComponent<Props, State> {
|
||||||
visible={this.hasNoBuckets}
|
visible={this.hasNoBuckets}
|
||||||
resourceName="Telegraf Configurations"
|
resourceName="Telegraf Configurations"
|
||||||
/>
|
/>
|
||||||
<GetLabels>
|
<GetResources resource={ResourceTypes.Labels}>
|
||||||
<FilterList<Telegraf>
|
<FilterList<Telegraf>
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
searchKeys={['plugins.0.config.bucket', 'labels[].name']}
|
searchKeys={['plugins.0.config.bucket', 'labels[].name']}
|
||||||
|
@ -119,7 +119,7 @@ class Collectors extends PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FilterList>
|
</FilterList>
|
||||||
</GetLabels>
|
</GetResources>
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
<Grid.Column
|
<Grid.Column
|
||||||
widthSM={Columns.Six}
|
widthSM={Columns.Six}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import TemplatesHeader from 'src/templates/components/TemplatesHeader'
|
||||||
import TemplatesList from 'src/templates/components/TemplatesList'
|
import TemplatesList from 'src/templates/components/TemplatesList'
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
|
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
|
||||||
import GetLabels from 'src/labels/components/GetLabels'
|
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {TemplateSummary, AppState} from 'src/types'
|
import {TemplateSummary, AppState} from 'src/types'
|
||||||
|
@ -50,7 +50,7 @@ class TemplatesPage extends PureComponent<Props, State> {
|
||||||
isFullPage={false}
|
isFullPage={false}
|
||||||
filterComponent={() => this.filterComponent}
|
filterComponent={() => this.filterComponent}
|
||||||
/>
|
/>
|
||||||
<GetLabels>
|
<GetResources resource={ResourceTypes.Labels}>
|
||||||
<FilterList<TemplateSummary>
|
<FilterList<TemplateSummary>
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
searchKeys={['meta.name', 'labels[].name']}
|
searchKeys={['meta.name', 'labels[].name']}
|
||||||
|
@ -65,7 +65,7 @@ class TemplatesPage extends PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FilterList>
|
</FilterList>
|
||||||
</GetLabels>
|
</GetResources>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {TimeMachinesState} from 'src/timeMachine/reducers'
|
||||||
import {AppState as AppPresentationState} from 'src/shared/reducers/app'
|
import {AppState as AppPresentationState} from 'src/shared/reducers/app'
|
||||||
import {TasksState} from 'src/tasks/reducers'
|
import {TasksState} from 'src/tasks/reducers'
|
||||||
import {RouterState} from 'react-router-redux'
|
import {RouterState} from 'react-router-redux'
|
||||||
import {MeState} from 'src/shared/reducers/v2/me'
|
import {MeState} from 'src/shared/reducers/me'
|
||||||
import {NoteEditorState} from 'src/dashboards/reducers/notes'
|
import {NoteEditorState} from 'src/dashboards/reducers/notes'
|
||||||
import {DataLoadingState} from 'src/dataLoaders/reducers'
|
import {DataLoadingState} from 'src/dataLoaders/reducers'
|
||||||
import {OnboardingState} from 'src/onboarding/reducers'
|
import {OnboardingState} from 'src/onboarding/reducers'
|
||||||
|
|
|
@ -14,7 +14,7 @@ import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader
|
||||||
import VariableList from 'src/variables/components/VariableList'
|
import VariableList from 'src/variables/components/VariableList'
|
||||||
import FilterList from 'src/shared/components/Filter'
|
import FilterList from 'src/shared/components/Filter'
|
||||||
import AddResourceDropdown from 'src/shared/components/AddResourceDropdown'
|
import AddResourceDropdown from 'src/shared/components/AddResourceDropdown'
|
||||||
import GetLabels from 'src/labels/components/GetLabels'
|
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {OverlayState} from 'src/types'
|
import {OverlayState} from 'src/types'
|
||||||
|
@ -65,7 +65,7 @@ class VariablesTab extends PureComponent<Props, State> {
|
||||||
onSelectNew={this.handleOpenCreateOverlay}
|
onSelectNew={this.handleOpenCreateOverlay}
|
||||||
/>
|
/>
|
||||||
</TabbedPageHeader>
|
</TabbedPageHeader>
|
||||||
<GetLabels>
|
<GetResources resource={ResourceTypes.Labels}>
|
||||||
<FilterList<Variable>
|
<FilterList<Variable>
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
searchKeys={['name', 'labels[].name']}
|
searchKeys={['name', 'labels[].name']}
|
||||||
|
@ -82,7 +82,7 @@ class VariablesTab extends PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FilterList>
|
</FilterList>
|
||||||
</GetLabels>
|
</GetResources>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue