Merge pull request #11885 from influxdata/feat(tempvars)/variables-list
Add ability to create a new template variablepull/11894/head
commit
dcfab169c6
ui
src
organizations
tasks/components
4
macro.go
4
macro.go
|
@ -124,10 +124,6 @@ func (m *Macro) Valid() error {
|
|||
return fmt.Errorf("invalid arguments type")
|
||||
}
|
||||
|
||||
if len(m.Selected) == 0 {
|
||||
return fmt.Errorf("no selected values")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
|
@ -838,9 +838,9 @@
|
|||
}
|
||||
},
|
||||
"@influxdata/influx": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@influxdata/influx/-/influx-0.2.5.tgz",
|
||||
"integrity": "sha512-K5arbttAaGIC3iuW5OcJxmy8+qtLRD9pfIoS7NtbN7PUL+NDIzIK7tMrUcvAIPPBREDc4W/lNuicoy79ukMhkw==",
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@influxdata/influx/-/influx-0.2.9.tgz",
|
||||
"integrity": "sha512-hS+FRtHH+zUVMRGDrlkUQaFUpbrKZUqE0zMD5TIPoYbK9dgKLcOF1pT36btzV2BsDNhwXD2SCHuXimzLaD2koQ==",
|
||||
"requires": {
|
||||
"axios": "^0.18.0"
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@influxdata/clockface": "0.0.2",
|
||||
"@influxdata/influx": "^0.2.3",
|
||||
"@influxdata/influx": "^0.2.9",
|
||||
"@influxdata/react-custom-scrollbars": "4.3.8",
|
||||
"axios": "^0.18.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
|
|
|
@ -19,9 +19,13 @@ import {
|
|||
import {Button} from '@influxdata/clockface'
|
||||
import FluxEditor from 'src/shared/components/FluxEditor'
|
||||
|
||||
// Types
|
||||
import {Macro} from '@influxdata/influx'
|
||||
|
||||
interface Props {
|
||||
onCreateVariable: () => void
|
||||
onCreateVariable: (variable: Macro) => Promise<void>
|
||||
onCloseModal: () => void
|
||||
orgID: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -88,7 +92,7 @@ export default class CreateOrgOverlay extends PureComponent<Props, State> {
|
|||
<Button
|
||||
text="Create"
|
||||
type={ButtonType.Submit}
|
||||
onClick={this.handleCreateVariable}
|
||||
onClick={this.handleSubmit}
|
||||
color={ComponentColor.Primary}
|
||||
/>
|
||||
</OverlayFooter>
|
||||
|
@ -98,8 +102,17 @@ export default class CreateOrgOverlay extends PureComponent<Props, State> {
|
|||
)
|
||||
}
|
||||
|
||||
private handleCreateVariable = () => {
|
||||
this.props.onCloseModal()
|
||||
private handleSubmit = (): void => {
|
||||
const {onCreateVariable, orgID} = this.props
|
||||
|
||||
onCreateVariable({
|
||||
name: this.state.name,
|
||||
orgID,
|
||||
arguments: {
|
||||
type: 'query',
|
||||
values: {query: this.state.script, language: 'flux'},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private handleChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
|
||||
// Components
|
||||
import {IndexList, Alignment} from 'src/clockface'
|
||||
|
||||
// Types
|
||||
import {Macro} from '@influxdata/influx'
|
||||
|
||||
interface Props {
|
||||
variable: Macro
|
||||
}
|
||||
|
||||
export default class VariableRow extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {variable} = this.props
|
||||
return (
|
||||
<IndexList.Row>
|
||||
<IndexList.Cell alignment={Alignment.Left}>
|
||||
{variable.name}
|
||||
</IndexList.Cell>
|
||||
<IndexList.Cell alignment={Alignment.Left}>{'Query'}</IndexList.Cell>
|
||||
</IndexList.Row>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -5,13 +5,28 @@ import _ from 'lodash'
|
|||
// Components
|
||||
import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader'
|
||||
import CreateVariableOverlay from 'src/organizations/components/CreateVariableOverlay'
|
||||
import {Button} from '@influxdata/clockface'
|
||||
import {Input, ComponentColor, IconFont, OverlayTechnology} from 'src/clockface'
|
||||
import {Button, ComponentSize} from '@influxdata/clockface'
|
||||
import VariablesList from 'src/organizations/components/VariablesList'
|
||||
import {
|
||||
Input,
|
||||
ComponentColor,
|
||||
IconFont,
|
||||
OverlayTechnology,
|
||||
EmptyState,
|
||||
} from 'src/clockface'
|
||||
import FilterList from 'src/shared/components/Filter'
|
||||
|
||||
// Types
|
||||
import {OverlayState} from 'src/types'
|
||||
import {client} from 'src/utils/api'
|
||||
import {Macro} from '@influxdata/influx'
|
||||
|
||||
interface Props {}
|
||||
interface Props {
|
||||
onChange: () => void
|
||||
variables: Macro[]
|
||||
orgName: string
|
||||
orgID: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
searchTerm: string
|
||||
|
@ -28,6 +43,7 @@ export default class Variables extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {variables, orgID} = this.props
|
||||
const {searchTerm, overlayState} = this.state
|
||||
|
||||
return (
|
||||
|
@ -48,10 +64,20 @@ export default class Variables extends PureComponent<Props, State> {
|
|||
onClick={this.handleOpenModal}
|
||||
/>
|
||||
</TabbedPageHeader>
|
||||
<FilterList<Macro>
|
||||
searchTerm={searchTerm}
|
||||
searchKeys={['name', 'ruleString']}
|
||||
list={variables}
|
||||
>
|
||||
{variables => (
|
||||
<VariablesList variables={variables} emptyState={this.emptyState} />
|
||||
)}
|
||||
</FilterList>
|
||||
<OverlayTechnology visible={overlayState === OverlayState.Open}>
|
||||
<CreateVariableOverlay
|
||||
onCreateVariable={this.handleCreateVariable}
|
||||
onCloseModal={this.handleCloseModal}
|
||||
orgID={orgID}
|
||||
/>
|
||||
</OverlayTechnology>
|
||||
</>
|
||||
|
@ -73,5 +99,37 @@ export default class Variables extends PureComponent<Props, State> {
|
|||
this.setState({overlayState: OverlayState.Closed})
|
||||
}
|
||||
|
||||
private handleCreateVariable() {}
|
||||
private handleCreateVariable = async (variable: Macro) => {
|
||||
await client.variables.create(variable)
|
||||
this.props.onChange()
|
||||
this.handleCloseModal()
|
||||
}
|
||||
|
||||
private get emptyState(): JSX.Element {
|
||||
const {orgName} = this.props
|
||||
const {searchTerm} = this.state
|
||||
|
||||
if (_.isEmpty(searchTerm)) {
|
||||
return (
|
||||
<EmptyState size={ComponentSize.Medium}>
|
||||
<EmptyState.Text
|
||||
text={`${orgName} does not own any Variables , why not create one?`}
|
||||
highlightWords={['Buckets']}
|
||||
/>
|
||||
<Button
|
||||
text="Create Variable"
|
||||
icon={IconFont.Plus}
|
||||
color={ComponentColor.Primary}
|
||||
onClick={this.handleOpenModal}
|
||||
/>
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<EmptyState size={ComponentSize.Medium}>
|
||||
<EmptyState.Text text="No Variables match your query" />
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
|
||||
// Components
|
||||
import {IndexList} from 'src/clockface'
|
||||
import VariableRow from 'src/organizations/components/VariableRow'
|
||||
|
||||
// Types
|
||||
import {Macro} from '@influxdata/influx'
|
||||
|
||||
interface Props {
|
||||
variables: Macro[]
|
||||
emptyState: JSX.Element
|
||||
}
|
||||
|
||||
class VariablesList extends PureComponent<Props> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {emptyState, variables} = this.props
|
||||
|
||||
return (
|
||||
<>
|
||||
<IndexList>
|
||||
<IndexList.Header>
|
||||
<IndexList.HeaderCell columnName="Name" width="60%" />
|
||||
<IndexList.HeaderCell columnName="Type" width="40%" />
|
||||
</IndexList.Header>
|
||||
<IndexList.Body columnCount={3} emptyState={emptyState}>
|
||||
{variables.map(variable => (
|
||||
<VariableRow key={variable.id} variable={variable} />
|
||||
))}
|
||||
</IndexList.Body>
|
||||
</IndexList>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default VariablesList
|
|
@ -26,7 +26,7 @@ import * as NotificationsActions from 'src/types/actions/notifications'
|
|||
import * as notifyActions from 'src/shared/actions/notifications'
|
||||
|
||||
const getBuckets = async (org: Organization) => {
|
||||
return client.buckets.getAllByOrg(org)
|
||||
return client.buckets.getAllByOrg(org.name)
|
||||
}
|
||||
|
||||
interface RouterProps {
|
||||
|
|
|
@ -11,12 +11,16 @@ const getCollectors = async (org: Organization) => {
|
|||
return client.telegrafConfigs.getAllByOrg(org)
|
||||
}
|
||||
|
||||
const getScrapers = async () => {
|
||||
const getScrapers = async (): Promise<ScraperTargetResponse[]> => {
|
||||
return await client.scrapers.getAll()
|
||||
}
|
||||
|
||||
const getBuckets = async (org: Organization) => {
|
||||
return client.buckets.getAllByOrg(org)
|
||||
const getBuckets = async (org: Organization): Promise<Bucket[]> => {
|
||||
return client.buckets.getAllByOrg(org.name)
|
||||
}
|
||||
|
||||
const getVariables = async (org: Organization): Promise<Macro[]> => {
|
||||
return await client.variables.getAllByOrg(org.name)
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
@ -44,6 +48,7 @@ import {
|
|||
ScraperTargetResponse,
|
||||
} from '@influxdata/influx'
|
||||
import * as NotificationsActions from 'src/types/actions/notifications'
|
||||
import {Macro} from '@influxdata/influx'
|
||||
|
||||
// Decorators
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
@ -54,7 +59,7 @@ interface StateProps {
|
|||
}
|
||||
|
||||
const getTasks = async (org: Organization): Promise<Task[]> => {
|
||||
const tasks = await client.tasks.getAllByOrg(org)
|
||||
const tasks = await client.tasks.getAllByOrg(org.name)
|
||||
const mappedTasks = tasks.map(task => {
|
||||
return {
|
||||
...task,
|
||||
|
@ -188,7 +193,26 @@ class OrganizationView extends PureComponent<Props> {
|
|||
url="variables_tab"
|
||||
title="Variables"
|
||||
>
|
||||
<Variables />
|
||||
<GetOrgResources<Macro[]>
|
||||
organization={org}
|
||||
fetcher={getVariables}
|
||||
>
|
||||
{(variables, loading, fetch) => {
|
||||
return (
|
||||
<SpinnerContainer
|
||||
loading={loading}
|
||||
spinnerComponent={<TechnoSpinner />}
|
||||
>
|
||||
<Variables
|
||||
onChange={fetch}
|
||||
variables={variables}
|
||||
orgName={org.name}
|
||||
orgID={org.id}
|
||||
/>
|
||||
</SpinnerContainer>
|
||||
)
|
||||
}}
|
||||
</GetOrgResources>
|
||||
</TabbedPageSection>
|
||||
</OrganizationTabs>
|
||||
</div>
|
||||
|
|
|
@ -46,7 +46,7 @@ interface State {
|
|||
schedule: TaskSchedule
|
||||
}
|
||||
|
||||
const getBuckets = (org: Organization) => client.buckets.getAllByOrg(org)
|
||||
const getBuckets = (org: Organization) => client.buckets.getAllByOrg(org.name)
|
||||
|
||||
export default class TaskForm extends PureComponent<Props, State> {
|
||||
public static defaultProps: Partial<Props> = {
|
||||
|
|
Loading…
Reference in New Issue