Merge pull request #13410 from influxdata/reorg-sweepthrough

Reorg sweepthrough
pull/13415/head
Deniz Kusefoglu 2019-04-15 14:13:28 -07:00 committed by GitHub
commit 4cb8a0632b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 34 additions and 919 deletions

View File

@ -78,7 +78,7 @@ export const getBuckets = () => async (
orgs: {org},
} = getState()
const buckets = (await client.buckets.getAll(org.id)) as Bucket[]
const buckets = await client.buckets.getAll(org.id)
dispatch(setBuckets(RemoteDataState.Done, buckets))
} catch (e) {

View File

@ -5,8 +5,8 @@ import _ from 'lodash'
// Components
import {IndexList, ConfirmationButton, Context} from 'src/clockface'
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
import EditableName from 'src/shared/components/EditableName'
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
// 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."
action={this.handleAddLineProtocol}
/>
<CloudFeatureFlag>
<CloudExclude>
<Context.Item
label="Scrape Metrics"
description="Add a scrape target to pull data into your bucket."
action={this.handleAddScraper}
/>
</CloudFeatureFlag>
</CloudExclude>
</Context.Menu>
</Context>
</IndexList.Cell>

View File

@ -5,7 +5,7 @@ import _ from 'lodash'
// Components
import Table from 'src/dashboards/components/dashboard_index/Table'
import FilterList from 'src/shared/components/Filter'
import GetLabels from 'src/labels/components/GetLabels'
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
@ -43,7 +43,7 @@ export default class DashboardsIndexContents extends Component<Props> {
} = this.props
return (
<GetLabels>
<GetResources resource={ResourceTypes.Labels}>
<FilterList<Dashboard>
list={dashboards}
searchTerm={searchTerm}
@ -64,7 +64,7 @@ export default class DashboardsIndexContents extends Component<Props> {
/>
)}
</FilterList>
</GetLabels>
</GetResources>
)
}
}

View File

@ -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(' ')
}

View File

@ -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)
})
})

View File

@ -1,9 +0,0 @@
import {toString} from './ast'
const InfluxQL = ast => {
return {
toString: () => toString(ast),
}
}
export default InfluxQL

View File

@ -73,13 +73,11 @@ export const getLabels = () => async (
) => {
try {
const {
orgs: {
org: {id},
},
orgs: {org},
} = getState()
dispatch(setLabels(RemoteDataState.Loading))
const labels = await client.labels.getAll(id)
const labels = await client.labels.getAll(org.id)
dispatch(setLabels(RemoteDataState.Done, labels))
} catch (e) {

View File

@ -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)

View File

@ -5,8 +5,8 @@ import {Link} from 'react-router'
// Components
import {NavMenu} from '@influxdata/clockface'
import {Organization} from '@influxdata/influx'
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
import SortingHat from 'src/shared/components/sorting_hat/SortingHat'
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
interface Props {
orgs: Organization[]
@ -29,7 +29,7 @@ class AccountNavSubItem extends PureComponent<Props> {
return (
<>
<CloudFeatureFlag key="feature-flag">
<CloudExclude key="feature-flag">
{orgs.length > 1 && (
<NavMenu.SubItem
titleLink={className => (
@ -50,7 +50,7 @@ class AccountNavSubItem extends PureComponent<Props> {
)}
active={false}
/>
</CloudFeatureFlag>
</CloudExclude>
<NavMenu.SubItem
titleLink={className => (

View File

@ -76,13 +76,12 @@ export const getScrapers = () => async (
) => {
try {
const {
orgs: {
org: {id},
},
orgs: {org},
} = getState()
dispatch(setScrapers(RemoteDataState.Loading))
const scrapers = await client.scrapers.getAll(id)
const scrapers = await client.scrapers.getAll(org.id)
dispatch(setScrapers(RemoteDataState.Done, scrapers))
} catch (e) {

View File

@ -7,7 +7,7 @@ import {Tabs} from 'src/clockface'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
import CloudFeatureFlag from 'src/shared/components/CloudFeatureFlag'
import CloudExclude from 'src/shared/components/cloud/CloudExclude'
interface Props {
tab: string
@ -41,14 +41,14 @@ class SettingsNavigation extends PureComponent<Props> {
url={`${route}/telegrafs`}
active={'telegrafs' === tab}
/>
<CloudFeatureFlag>
<CloudExclude>
<Tabs.Tab
title="Scrapers"
id="scrapers"
url={`${route}/scrapers`}
active={'scrapers' === tab}
/>
</CloudFeatureFlag>
</CloudExclude>
<Tabs.Tab
title="Variables"
id="variables"

View File

@ -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'
export enum ActionTypes {

View File

@ -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
}
}

View File

@ -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)

View File

@ -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)
})
})
})
})

View File

@ -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)

View File

@ -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

View File

@ -9,7 +9,7 @@ import {SpinnerContainer, TechnoSpinner} from '@influxdata/clockface'
import {RemoteDataState} from 'src/types'
// Actions
import {getMe} from 'src/shared/actions/v2/me'
import {getMe} from 'src/shared/actions/me'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'

View File

@ -1,4 +1,4 @@
import {Actions, ActionTypes} from 'src/shared/actions/v2/me'
import {Actions, ActionTypes} from 'src/shared/actions/me'
export interface MeLinks {
self: string

View File

@ -10,7 +10,7 @@ import sharedReducers from 'src/shared/reducers'
import persistStateEnhancer from './persistStateEnhancer'
// v2 reducers
import meReducer from 'src/shared/reducers/v2/me'
import meReducer from 'src/shared/reducers/me'
import tasksReducer from 'src/tasks/reducers'
import rangesReducer from 'src/dashboards/reducers/ranges'
import {dashboardsReducer} from 'src/dashboards/reducers/dashboards'

View File

@ -10,7 +10,6 @@ import {Page} from 'src/pageLayout'
import {ErrorHandling} from 'src/shared/decorators/errors'
import FilterList from 'src/shared/components/Filter'
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
import GetLabels from 'src/labels/components/GetLabels'
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
// Actions
@ -106,7 +105,7 @@ class TasksPage extends PureComponent<Props, State> {
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<GetResources resource={ResourceTypes.Tasks}>
<GetLabels>
<GetResources resource={ResourceTypes.Labels}>
<FilterList<Task>
list={this.filteredTasks}
searchTerm={searchTerm}
@ -133,7 +132,7 @@ class TasksPage extends PureComponent<Props, State> {
)}
</FilterList>
{this.hiddenTaskAlert}
</GetLabels>
</GetResources>
</GetResources>
</div>
</Page.Contents>

View File

@ -11,7 +11,7 @@ import CollectorList from 'src/telegrafs/components/CollectorList'
import TelegrafExplainer from 'src/telegrafs/components/TelegrafExplainer'
import FilterList from 'src/shared/components/Filter'
import NoBucketsWarning from 'src/buckets/components/NoBucketsWarning'
import GetLabels from 'src/labels/components/GetLabels'
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
// Actions
import {setBucketInfo} from 'src/dataLoaders/actions/steps'
@ -102,7 +102,7 @@ class Collectors extends PureComponent<Props, State> {
visible={this.hasNoBuckets}
resourceName="Telegraf Configurations"
/>
<GetLabels>
<GetResources resource={ResourceTypes.Labels}>
<FilterList<Telegraf>
searchTerm={searchTerm}
searchKeys={['plugins.0.config.bucket', 'labels[].name']}
@ -119,7 +119,7 @@ class Collectors extends PureComponent<Props, State> {
/>
)}
</FilterList>
</GetLabels>
</GetResources>
</Grid.Column>
<Grid.Column
widthSM={Columns.Six}

View File

@ -9,7 +9,7 @@ import TemplatesHeader from 'src/templates/components/TemplatesHeader'
import TemplatesList from 'src/templates/components/TemplatesList'
import {ErrorHandling} from 'src/shared/decorators/errors'
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
import {TemplateSummary, AppState} from 'src/types'
@ -50,7 +50,7 @@ class TemplatesPage extends PureComponent<Props, State> {
isFullPage={false}
filterComponent={() => this.filterComponent}
/>
<GetLabels>
<GetResources resource={ResourceTypes.Labels}>
<FilterList<TemplateSummary>
searchTerm={searchTerm}
searchKeys={['meta.name', 'labels[].name']}
@ -65,7 +65,7 @@ class TemplatesPage extends PureComponent<Props, State> {
/>
)}
</FilterList>
</GetLabels>
</GetResources>
</>
)
}

View File

@ -5,7 +5,7 @@ import {TimeMachinesState} from 'src/timeMachine/reducers'
import {AppState as AppPresentationState} from 'src/shared/reducers/app'
import {TasksState} from 'src/tasks/reducers'
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 {DataLoadingState} from 'src/dataLoaders/reducers'
import {OnboardingState} from 'src/onboarding/reducers'

View File

@ -14,7 +14,7 @@ import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader
import VariableList from 'src/variables/components/VariableList'
import FilterList from 'src/shared/components/Filter'
import AddResourceDropdown from 'src/shared/components/AddResourceDropdown'
import GetLabels from 'src/labels/components/GetLabels'
import GetResources, {ResourceTypes} from 'src/shared/components/GetResources'
// Types
import {OverlayState} from 'src/types'
@ -65,7 +65,7 @@ class VariablesTab extends PureComponent<Props, State> {
onSelectNew={this.handleOpenCreateOverlay}
/>
</TabbedPageHeader>
<GetLabels>
<GetResources resource={ResourceTypes.Labels}>
<FilterList<Variable>
searchTerm={searchTerm}
searchKeys={['name', 'labels[].name']}
@ -82,7 +82,7 @@ class VariablesTab extends PureComponent<Props, State> {
/>
)}
</FilterList>
</GetLabels>
</GetResources>
</>
)
}